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)} 压缩成功");
// 上传到Box
await 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-parser
Box.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"