告别WinRAR!用C#和SharpCompress搞定RAR/ZIP/7Z压缩解压(附完整代码)
告别WinRAR用C#和SharpCompress搞定RAR/ZIP/7Z压缩解压附完整代码还在为项目中的压缩解压需求频繁切换WinRAR和7-Zip而烦恼或是受够了商业组件高昂的授权费用今天我们将彻底摆脱这些束缚用纯.NET方案SharpCompress实现全格式压缩解压自由。这个开源库不仅能处理ZIP、7Z等常见格式还能破解RAR解压的难题——虽然它目前不支持RAR压缩但这已经足够让90%的日常开发场景变得轻松。1. 为什么选择SharpCompress传统.NET开发中处理压缩文件通常有三种方式调用WinRAR命令行、使用System.IO.Compression命名空间或者购买商业组件。让我们用表格对比它们的核心差异方案免费纯.NETRAR支持多格式支持易用性WinRAR命令行✔✔System.IO.Compression✔✔商业组件✔✔✔SharpCompress✔✔✔解压✔SharpCompress的独特优势在于零成本集成MIT许可证允许商业项目无偿使用格式全覆盖支持读取RAR5等最新压缩格式流式处理无需完全加载文件即可开始解压跨平台完美运行在.NET Core/.NET 5环境注意虽然SharpCompress能解压RAR但由于RAR的专利限制压缩RAR功能暂不可用。对于需要RAR压缩的场景建议配合7-Zip命令行作为补充方案。2. 快速入门指南2.1 安装与基础配置通过NuGet安装只需一行命令dotnet add package SharpCompress或者直接在Visual Studio的NuGet包管理器中搜索SharpCompress。安装后在代码文件中添加引用using SharpCompress.Archives; using SharpCompress.Archives.Zip; using SharpCompress.Common; using SharpCompress.Writers;2.2 核心API速览SharpCompress主要提供两类API高级APIArchiveFactory和WriterFactory适合简单场景低级APIIReader和IWriter接口提供更精细控制推荐开发顺序先用高级API实现基本功能遇到性能瓶颈时改用低级API优化对特定格式有特殊需求时查阅对应格式的专属API3. 实战代码示例3.1 ZIP文件处理全攻略压缩文件夹到ZIPstring sourceDir D:\ProjectAssets; string zipPath C:\Backups\project_202308.zip; using (var zipStream File.Create(zipPath)) using (var writer WriterFactory.Open(zipStream, ArchiveType.Zip, CompressionType.Deflate)) { writer.WriteAll(sourceDir, *, SearchOption.AllDirectories, filePath Path.GetRelativePath(sourceDir, filePath)); }解压ZIP到指定目录var archive ArchiveFactory.Open(C:\Downloads\package.zip); foreach (var entry in archive.Entries.Where(e !e.IsDirectory)) { entry.WriteToDirectory(D:\Extracted, new ExtractionOptions { ExtractFullPath true, Overwrite true, PreserveFileTime true }); }3.2 处理7Z和RAR文件虽然不能创建这些格式但解压非常简便7Z解压示例using (var archive ArchiveFactory.Open(C:\Temp\large_file.7z)) { var report new StringBuilder(); foreach (var entry in archive.Entries) { if (!entry.IsDirectory) { report.AppendLine($解压: {entry.Key} ({entry.Size}字节)); entry.WriteToDirectory(D:\Output, new ExtractionOptions { Overwrite true }); } } File.WriteAllText(C:\Temp\extraction_log.txt, report.ToString()); }RAR解压特殊处理var rarPath E:\Downloads\dataset.part1.rar; var options new ReaderOptions { LookForHeader true, Password secure123 // 支持加密压缩包 }; using (var archive ArchiveFactory.Open(rarPath, options)) { archive.Entries .Where(e !e.IsDirectory) .AsParallel() // 多线程解压提升速度 .ForAll(entry { string targetPath Path.Combine(F:\Data, entry.Key); entry.WriteToFile(targetPath, new ExtractionOptions { Overwrite true }); }); }3.3 高级技巧内存流压缩需要临时压缩数据而不产生物理文件试试内存流方案byte[] CompressInMemory(Dictionarystring, byte[] files) { using (var ms new MemoryStream()) { using (var writer WriterFactory.Open(ms, ArchiveType.Zip, CompressionType.BZip2)) { foreach (var file in files) { using (var fileStream new MemoryStream(file.Value)) { writer.Write(file.Key, fileStream); } } } return ms.ToArray(); } }4. 性能优化与异常处理4.1 大文件处理策略遇到GB级压缩包时采用分块读取模式var options new ReaderOptions { DisableCheckIncomplete true, LookForHeader true }; using (var archive ArchiveFactory.Open(\\NAS\large_backup.zip, options)) { var buffer new byte[8192]; foreach (var entry in archive.Entries.Where(e !e.IsDirectory)) { using (var entryStream entry.OpenEntryStream()) { int bytesRead; while ((bytesRead entryStream.Read(buffer, 0, buffer.Length)) 0) { // 处理数据块 ProcessChunk(buffer, bytesRead); } } } }4.2 常见错误处理完善的异常捕获应包括try { using (var archive ArchiveFactory.Open(zipPath)) { // 处理逻辑 } } catch (InvalidFormatException ex) { Console.WriteLine($文件格式无效: {ex.Message}); } catch (CryptographicException ex) { Console.WriteLine($密码错误或加密损坏: {ex.Message}); } catch (IOException ex) { Console.WriteLine($I/O错误: {ex.Message}); } finally { // 清理资源 }4.3 进度监控实现通过自定义IExtractionListener实现进度回调public class ProgressReporter : IExtractionListener { public void OnFileEntryExtractionBegin(IEntry entry) { Console.WriteLine($开始解压: {entry.Key}); } public void OnFileEntryExtractionEnd(IEntry entry, long size) { Console.WriteLine($完成解压: {entry.Key} ({size}字节)); } } // 使用方式 var options new ExtractionOptions { ExtractionListener new ProgressReporter() }; entry.WriteToDirectory(outputPath, options);5. 实际应用场景扩展5.1 自动化备份系统结合SharpCompress和FileSystemWatcher创建实时备份工具var watcher new FileSystemWatcher(D:\ImportantFiles); watcher.Created (sender, e) { string backupName $backup_{DateTime.Now:yyyyMMddHHmm}.zip; using (var zip File.OpenWrite(Path.Combine(\\BackupServer, backupName))) using (var writer WriterFactory.Open(zip, ArchiveType.Zip, CompressionType.Deflate)) { writer.WriteAll(D:\ImportantFiles, *, SearchOption.AllDirectories); } }; watcher.EnableRaisingEvents true;5.2 WebAPI文件处理在ASP.NET Core中实现压缩下载[HttpGet(download)] public IActionResult DownloadReports([FromQuery] string[] files) { var ms new MemoryStream(); using (var writer WriterFactory.Open(ms, ArchiveType.Zip, CompressionType.Deflate)) { foreach (var file in files) { if (System.IO.File.Exists(file)) { writer.Write(Path.GetFileName(file), file); } } } ms.Position 0; return File(ms, application/zip, reports.zip); }5.3 数据库备份压缩配合Entity Framework Core实现数据库备份压缩public async Taskbyte[] BackupDatabaseAsync() { var tempFile Path.GetTempFileName(); try { await using (var dbStream File.Create(tempFile)) { await _context.Database.OpenConnectionAsync(); await _context.Database.ExecuteSqlRawAsync( $BACKUP DATABASE [{_context.Database.GetDbConnection().Database}] TO DISK{tempFile}); } using (var ms new MemoryStream()) { using (var writer WriterFactory.Open(ms, ArchiveType.SevenZip, CompressionType.LZMA)) { writer.Write(database_backup.bak, tempFile); } return ms.ToArray(); } } finally { File.Delete(tempFile); } }SharpCompress在实际项目中的表现远超预期特别是在持续集成环境中它帮助我们实现了构建产物的自动打包和部署。虽然RAR压缩的缺失偶尔会带来不便但通过组合7Z格式和适当的脚本处理这个痛点已经变得可以接受。