C#批量压缩并上载CSV数据文件到Box企业云盘
C# .NET 8实现Windows下批量压缩csv文件为zip文件,然后异步上传到box企业云服务网盘路径,实现异常处理和写入运行状态日志,参数来自ini配置文件。
C# .NET 8代码示例,包含INI配置读取、CSV文件压缩、Box上传、异步处理和日志记录功能:
using System.Collections.Concurrent;
using System.IO.Compression;
using IniParser;
using IniParser.Model;
using Box.V2;
using Box.V2.Auth;
using Box.V2.Config;
using Box.V2.Models;class Program
{private static readonly object _logLock = new object();private static string _logPath;static async Task Main(string[] args){try{// 读取配置文件var config = LoadConfiguration("config.ini");// 初始化Box客户端var boxClient = InitializeBoxClient(config);// 处理文件await ProcessFilesAsync(config, boxClient);}catch (Exception ex){Log($"全局异常: {ex.Message}");}}static Configuration LoadConfiguration(string configPath){var parser = new FileIniDataParser();IniData iniData = parser.ReadFile(configPath);return new Configuration{ClientId = iniData["BoxConfig"]["ClientId"],ClientSecret = iniData["BoxConfig"]["ClientSecret"],AccessToken = iniData["BoxConfig"]["AccessToken"],UploadFolderId = iniData["BoxConfig"]["UploadFolderId"],SourceFolder = iniData["FileConfig"]["SourceFolder"],ZipFolder = iniData["FileConfig"]["ZipFolder"],LogPath = iniData["FileConfig"]["LogPath"]};}static BoxClient InitializeBoxClient(Configuration config){_logPath = config.LogPath;var auth = new OAuthSession(config.AccessToken, "N/A", 3600, "bearer");var boxConfig = new BoxConfigBuilder(config.ClientId, config.ClientSecret, new Uri("http://localhost")).Build();return new BoxClient(boxConfig, auth);}static async Task ProcessFilesAsync(Configuration config, BoxClient boxClient){try{Directory.CreateDirectory(config.ZipFolder);Directory.CreateDirectory(Path.GetDirectoryName(_logPath));var csvFiles = Directory.GetFiles(config.SourceFolder, "*.csv");Log($"找到 {csvFiles.Length} 个CSV文件需要处理");var tasks = new ConcurrentBag<Task>();Parallel.ForEach(csvFiles, csvFile =>{tasks.Add(ProcessSingleFileAsync(csvFile, config, boxClient));});await Task.WhenAll(tasks);Log("所有文件处理完成");}catch (Exception ex){Log($"文件处理异常: {ex.Message}");}}static async Task ProcessSingleFileAsync(string csvFile, Configuration config, BoxClient boxClient){try{string zipFileName = $"{Path.GetFileNameWithoutExtension(csvFile)}_{DateTime.Now:yyyyMMddHHmmss}.zip";string zipPath = Path.Combine(config.ZipFolder, zipFileName);// 压缩文件CreateZipFile(csvFile, zipPath);Log($"文件 {Path.GetFileName(csvFile)} 压缩成功");// 上传到Boxawait UploadToBoxAsync(boxClient, zipPath, config.UploadFolderId);Log($"文件 {zipFileName} 上传成功");// 清理临时压缩文件(可选)File.Delete(zipPath);}catch (Exception ex){Log($"处理文件 {Path.GetFileName(csvFile)} 失败: {ex.Message}");}}static void CreateZipFile(string sourceFile, string zipPath){using (var zipArchive = ZipFile.Open(zipPath, ZipArchiveMode.Create)){zipArchive.CreateEntryFromFile(sourceFile, Path.GetFileName(sourceFile));}}static async Task UploadToBoxAsync(BoxClient client, string filePath, string folderId){using (var fileStream = new FileStream(filePath, FileMode.Open)){var fileRequest = new BoxFileRequest{Name = Path.GetFileName(filePath),Parent = new BoxRequestEntity { Id = folderId }};await client.FilesManager.UploadAsync(fileRequest, fileStream);}}static void Log(string message){string logEntry = $"{DateTime.Now:yyyy-MM-dd HH:mm:ss} - {message}";lock (_logLock){File.AppendAllText(_logPath, logEntry + Environment.NewLine);}}
}public class Configuration
{public string ClientId { get; set; }public string ClientSecret { get; set; }public string AccessToken { get; set; }public string UploadFolderId { get; set; }public string SourceFolder { get; set; }public string ZipFolder { get; set; }public string LogPath { get; set; }
}
实现说明:
-
配置管理:
- 使用
IniParser包读取INI配置文件 - 配置参数包括Box认证信息、文件路径和日志路径
- Configuration类用于存储配置参数
- 使用
-
Box客户端初始化:
- 使用OAuth 2.0认证
- 需要有效的访问令牌(AccessToken)
-
文件处理:
- 使用并行处理加速文件压缩(Parallel.ForEach)
- 每个文件生成带时间戳的唯一ZIP文件名
- 自动清理临时压缩文件(可选)
-
异步上传:
- 使用Box官方SDK的异步上传方法
- 支持大文件分块上传(SDK自动处理)
-
日志记录:
- 线程安全的日志写入机制
- 包含时间戳和详细操作记录
- 支持并发写入时的文件锁定
-
异常处理:
- 多层异常捕获(全局、文件处理、单个文件)
- 详细的错误信息记录
配置示例(config.ini):
[BoxConfig]
ClientId = your_client_id
ClientSecret = your_client_secret
AccessToken = your_access_token
UploadFolderId = 0[FileConfig]
SourceFolder = C:\CSVFiles
ZipFolder = C:\TempZips
LogPath = C:\Logs\upload.log
注意事项:
-
Box认证:
- 需要有效的Box开发者账号和企业配置
- 建议使用JWT认证代替直接访问令牌(需修改认证逻辑)
-
性能优化:
- 根据网络情况调整并行处理数量
- 添加重试逻辑处理网络波动
-
安全增强:
- 敏感信息(如ClientSecret)建议加密存储
- 使用配置文件权限控制
-
扩展功能:
- 添加文件校验(MD5校验和)
- 实现增量上传功能
- 添加压缩密码保护
-
错误处理:
- 添加不同异常类型的处理逻辑
- 实现死信队列处理持续失败文件
使用时需要安装以下NuGet包:
ini-parserBox.V2
安装包和发布Release版程序的脚本:
cd <.csproj文件所在的目录>
dotnet add package Box.V2
dotnet add package ini-parser
dotnet build <.csproj文件完整路径> /property:GenerateFullPaths=true /consoleloggerparameters:NoSummary /p:Configuration=Release /p:Platform="AnyCPU"
相关文章:
C#批量压缩并上载CSV数据文件到Box企业云盘
C# .NET 8实现Windows下批量压缩csv文件为zip文件,然后异步上传到box企业云服务网盘路径,实现异常处理和写入运行状态日志,参数来自ini配置文件。 C# .NET 8代码示例,包含INI配置读取、CSV文件压缩、Box上传、异步处理和日志记录…...
C++常见概念
第一个 C 程序 #include<iostream>using namespace std;int main() {cout << "helloworld" << endl;return 0; }命名空间 #include<stdio.h>int rand 10;int main() {printf("%d", rand);return 0; }#include<stdio.h> #…...
结构型模式---享元模式
概念 享元模式是一种结构型设计模式,他摒弃了在每个对象中保存所有数据的方式,通过共享多个对象所共有的相同状态,让你能在有限的内存容量中载入更多对象。享元模式将原始类中的数据分为内在状态数据和外在状态数据。 内在状态:就…...
2025年渗透测试面试题总结- 深某服-漏洞研究员实习(题目+回答)
网络安全领域各种资源,学习文档,以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具,欢迎关注。 目录 深信服-漏洞研究员实习 1. 在XX实习时做了什么 2. 渗透测试的思路简单描述 3. 护网中承担什么角色 4…...
(13)Anaconda 安装配置详解
1. Anaconda 简介 Anaconda 是一个用于科学计算和数据分析的 Python 发行版,它集成了 Python 解释器、大量常用的科学计算库以及强大的包管理工具。 2. Anaconda 主要特点 丰富的库集合:包含了超过 1500 个用于科学计算、数据分析、机器学习等领域的常用 Python 库,例如 N…...
MWC 2025 | 移远通信大模型解决方案加速落地,引领服务机器人创新变革
随着人工智能、大模型等技术的蓬勃发展,生成式AI应用全面爆发。在此背景下,服务机器人作为大模型技术在端侧落地的关键场景,迎来了前所未有的发展机遇。 作为与用户直接交互的智能设备,服务机器人需要应对复杂场景下的感知、决策和…...
[内网安全] Windows 域认证 — Kerberos 协议认证
🌟想系统化学习内网渗透?看看这个:[内网安全] 内网渗透 - 学习手册-CSDN博客 0x01:Kerberos 协议简介 Kerberos 是一种网络认证协议,其设计目标是通过密钥系统为客户机 / 服务器应用程序提供强大的认证服务。该认证过…...
[Computer Vision]实验七:图像检索
目录 一、实验内容 二、实验过程 2.1 准备数据集 2.2 SIFT特征提取 2.3 学习“视觉词典”(vision vocabulary) 2.4 建立图像索引并保存到数据库中 2.5 用一幅图像查询 三、实验小结 一、实验内容 实现基于颜色直方图、bag of word等方法的以图搜…...
C++之thread_local变量
C之thread_local变量_c threadlocal-CSDN博客 thread_local简介 thread_local 是 C11 为线程安全引进的变量声明符。表示对象的生命周期属于线程存储期。 线程局部存储(Thread Local Storage,TLS)是一种存储期(storage duration),对象的存储是在…...
【国产Linux | 银河麒麟】麒麟化龙——KylinOS下载到安装一条龙服务,起飞!
🗺️博客地图 📍一、下载地址 📍二、 系统安装 本文基于Windows操作系统vmware虚拟机安装 一、下载地址 官网:产品试用申请国产操作系统、麒麟操作系统——麒麟软件官方网站 下载自己需要的版本,完成后,…...
(接“使用js去复制网页内容的方法”)js中的execCommand怎么复制富文本内容解析
document.execCommand(copy) 是传统的剪贴板操作方法,但它主要用于复制纯文本内容。如果你想复制富文本内容(包括 HTML 标签和样式),需要结合一些技巧来实现。以下是具体方法: 方法:通过创建隐藏的富文本元…...
npm ERR! code 128 npm ERR! An unknown git error occurred
【问题描述】 【问题解决】 管理员运行cmd(右键window --> 选择终端管理员) 执行命令 git config --global url.“https://”.insteadOf ssh://git cd 到项目目录 重新执行npm install 个人原因,这里执行npm install --registryhttps:…...
解决Leetcode第3470题全排列IV
3470.全排列IV 难度:困难 问题描述: 给你两个整数n和k,一个交替排列是前n个正整数的排列,且任意相邻两个元素不都为奇数或都为偶数。 返回第k个交替排列,并按字典序排序。如果有效的交替排列少于k个,则…...
MyBatis 配置文件核心
MyBatis 配置文件核心标签解析 以下是针对你的笔记中的三个核心标签的详细解析,帮助你全面理解它们的用途和配置逻辑。 1. properties 标签:动态加载外部配置 功能 将环境相关的配置(如数据库连接、密钥等)与 MyBatis 核心配置…...
bert模型笔记
1.各预训练模型说明 BERT模型在英文数据集上提供了两种大小的模型,Base和Large。Uncased是意味着输入的词都会转变成小写,cased是意味着输入的词会保存其大写(在命名实体识别等项目上需要)。Multilingual是支持多语言的࿰…...
微信小程序接入deepseek
先上效果 话不多说,直接上代码(本人用的hbuilder Xuniapp) <template><view class"container"><!-- 聊天内容区域 --><scroll-view class"chat-list" scroll-y :scroll-top"scrollTop":…...
推荐算法和推荐系统入门第一趴
以下是推荐系统技术总结的架构梳理和建议表达思路: 从原理到生产环境:推荐系统核心技术与实战代码解析 一、推荐算法的演进图谱 传统算法三剑客 ![推荐系统算法分类示意图] (使用Mermaid绘制算法分类关系图,清晰展示技术演进&am…...
unity pico开发 四 物体交互 抓取 交互层级
文章目录 手部设置物体交互物体抓取添加抓取抓取三种类型抓取点偏移抓取事件抓取时不让物体吸附到手部 射线抓取交互层级 手部设置 为手部(LeftHandController)添加XRDirInteractor脚本 并添加一个球形碰撞盒,勾选isTrigger,调整大小为0.1 …...
基于深度学习的青花瓷图像检索系统开发与实现
目录 1.研究背景与目的 1.1课题背景 1.2研究目的 二、调研资料情况 2.1图像分割研究现状 2.2图像检索调研 2.2.1选择深度学习进行检索的原因及优势 2.2.2基于深度学习的图像检索技术的发展 2.2.3基于深度学习的图像检索的研究重点 2.3基于深度学习的图像检索方法调研 …...
uniapp 系统学习,从入门到实战(八)—— Vuex 的使用
全篇大概 4500 字(含代码),建议阅读时间 30min 📚 目录 Vuex核心概念解析在 UniApp 中集成Vuex状态管理与数据共享实践总结 一、Vuex 核心概念解析 1.1 什么是状态管理 在跨多组件的大型应用中,不同页面/组件需要共享和修改相同数据时&am…...
【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型
摘要 拍照搜题系统采用“三层管道(多模态 OCR → 语义检索 → 答案渲染)、两级检索(倒排 BM25 向量 HNSW)并以大语言模型兜底”的整体框架: 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后,分别用…...
【Linux】shell脚本忽略错误继续执行
在 shell 脚本中,可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行,可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令,并忽略错误 rm somefile…...
RocketMQ延迟消息机制
两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数,对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后…...
docker详细操作--未完待续
docker介绍 docker官网: Docker:加速容器应用程序开发 harbor官网:Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台,用于将应用程序及其依赖项(如库、运行时环…...
《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》
引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...
STM32+rt-thread判断是否联网
一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...
在Ubuntu中设置开机自动运行(sudo)指令的指南
在Ubuntu系统中,有时需要在系统启动时自动执行某些命令,特别是需要 sudo权限的指令。为了实现这一功能,可以使用多种方法,包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法,并提供…...
Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!
一、引言 在数据驱动的背景下,知识图谱凭借其高效的信息组织能力,正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合,探讨知识图谱开发的实现细节,帮助读者掌握该技术栈在实际项目中的落地方法。 …...
mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包
文章目录 现象:mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时,可能是因为以下几个原因:1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...
R语言速释制剂QBD解决方案之三
本文是《Quality by Design for ANDAs: An Example for Immediate-Release Dosage Forms》第一个处方的R语言解决方案。 第一个处方研究评估原料药粒径分布、MCC/Lactose比例、崩解剂用量对制剂CQAs的影响。 第二处方研究用于理解颗粒外加硬脂酸镁和滑石粉对片剂质量和可生产…...
