SharpCompress实战:一个方法搞定C#里ZIP压缩打包,附赠RAR/7Z解压和TAR.GZ创建教程
C#压缩解压全能手册用SharpCompress玩转ZIP/RAR/7Z/TAR.GZ在开发日志管理系统、文件上传模块或数据备份工具时文件压缩解压功能就像空气一样不可或缺。但面对ZIP、RAR、7Z、TAR.GZ这些格式各异的压缩包不少开发者都会陷入API选择的困境。SharpCompress这个轻量级库用统一的API设计让我们能用几乎相同的代码风格处理所有主流压缩格式。1. 环境准备与核心概念在Visual Studio中新建一个控制台项目通过NuGet添加SharpCompress只需两步右键点击项目选择管理NuGet程序包搜索框中输入SharpCompress并安装最新稳定版SharpCompress支持六种存档格式和九种压缩类型但需要注意几个关键特性格式类型压缩支持解压支持典型应用场景ZIP✔✔通用文件打包RAR✘✔解压用户上传文件7Z✘✔高压缩率场景TAR.GZ✔✔Linux系统备份TAR.BZ2✔✔大文件分卷压缩提示RAR格式由于专利限制SharpCompress仅支持解压。如需压缩RAR需要考虑调用WinRAR命令行工具。2. ZIP文件全流程操作ZIP作为最通用的压缩格式SharpCompress提供了完整的支持。假设我们要将日志目录打包成ZIP并上传// 压缩日志目录 var logPath C:\Logs\2023; var zipPath C:\Upload\logs_2023.zip; using (var zipStream File.Create(zipPath)) using (var writer WriterFactory.Open(zipStream, ArchiveType.Zip, CompressionType.Deflate)) { writer.WriteAll(logPath, *.*, SearchOption.AllDirectories); Console.WriteLine($ZIP压缩完成大小{new FileInfo(zipPath).Length / 1024}KB); } // 解压ZIP示例 var extractPath D:\ExtractedLogs; using (var archive ArchiveFactory.Open(zipPath)) { foreach (var entry in archive.Entries.Where(e !e.IsDirectory)) { entry.WriteToDirectory(extractPath, new ExtractionOptions { ExtractFullPath true, Overwrite true }); Console.WriteLine($解压: {entry.Key}); } }这段代码演示了几个实用技巧SearchOption.AllDirectories参数实现递归目录压缩使用Where过滤掉目录条目只处理文件通过ExtractionOptions控制解压行为3. 处理仅解压格式RAR和7Z当用户上传RAR或7Z格式时我们可以用几乎相同的模式处理// RAR解压通用方法 void ExtractRar7z(string archivePath, string outputDir) { using (var stream File.OpenRead(archivePath)) using (var reader ReaderFactory.Open(stream)) { while (reader.MoveToNextEntry()) { if (!reader.Entry.IsDirectory) { Console.WriteLine($正在解压: {reader.Entry.Key}); reader.WriteEntryToDirectory(outputDir, new ExtractionOptions { ExtractFullPath true, Overwrite true }); } } } } // 使用示例 ExtractRar7z(C:\Upload\user_data.rar, D:\UserData); ExtractRar7z(E:\Backup\project.7z, D:\ProjectBackup);注意几个常见问题处理中文文件名乱码设置ExtractionOptions的Encoding属性密码保护压缩包使用ReaderOptions的Password参数大文件内存优化通过Entry的OpenEntryStream()流式处理4. Linux友好格式TAR.GZ实战在跨平台场景下TAR.GZ是更优选择。下面是创建增量备份的示例void CreateIncrementalBackup(string sourceDir, string backupPath, DateTime lastBackupTime) { using (var tarStream File.Create(backupPath)) using (var writer WriterFactory.Open(tarStream, ArchiveType.Tar, CompressionType.GZip)) { var files Directory.GetFiles(sourceDir, *, SearchOption.AllDirectories) .Where(f File.GetLastWriteTime(f) lastBackupTime); foreach (var file in files) { var relativePath file.Substring(sourceDir.Length); writer.Write(relativePath, file); Console.WriteLine($已添加: {relativePath}); } } } // 使用示例 var lastBackup new DateTime(2023, 6, 1); CreateIncrementalBackup(C:\Website, D:\Backup\wwwroot_20230615.tar.gz, lastBackup);对于数据库备份等场景可以结合BZip2获得更高压缩率using (var stream File.Create(D:\Backup\db_20230615.tar.bz2)) using (var writer WriterFactory.Open(stream, ArchiveType.Tar, CompressionType.BZip2)) { writer.Write(dump.sql, C:\Temp\mysql_dump.sql); }5. 高级技巧与性能优化处理大文件时内存管理尤为关键。以下是几个实战建议流式处理大文件using (var archive ArchiveFactory.Open(largeZipPath)) { var bigFileEntry archive.Entries.First(e e.Key.EndsWith(.iso)); using (var entryStream bigFileEntry.OpenEntryStream()) using (var fileStream File.Create(D:\LargeFiles\output.iso)) { entryStream.CopyTo(fileStream); // 分块传输避免内存溢出 } }多线程压缩优化Parallel.ForEach(Directory.GetFiles(sourceDir), file { var entryName Path.GetFileName(file); lock (zipWriter) { zipWriter.Write(entryName, file); } });异常处理模板try { using (var archive ArchiveFactory.Open(corruptZipPath)) { // 处理条目 } } catch (InvalidFormatException ex) { Console.WriteLine($文件损坏: {ex.Message}); File.Move(corruptZipPath, corruptZipPath .invalid); } catch (CryptographicException ex) { Console.WriteLine($需要密码: {ex.Message}); // 弹出密码输入对话框 }实际项目中我发现对超过2GB的文件使用WriteEntryToDirectory可能会遇到内存问题。这时改用OpenEntryStream配合FileStream写入会更可靠特别是在IIS等托管环境中。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2625309.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!