核心库NewLife.Core内置了压缩相关功能扩展,并且独立实现的ZipFile还支持.NET2.0和.NET4.0,该类在.NET4.5以后成为.NET Framework框架标配。
Nuget包:NewLife.Core
源码:https://github.com/NewLifeX/X/blob/master/NewLife.Core/IO/IOHelper.cs
视频:https://www.bilibili.com/video/BV1ed4y1i75o
数据流压缩
IOHelper类扩展了字节数组和数据流的压缩扩展方法
Byte[] Compress(this Byte[] data); Byte[] Decompress(this Byte[] data); Stream Compress(this Stream inStream, Stream outStream = null); Stream Decompress(this Stream inStream, Stream outStream = null); Stream CompressGZip(this Stream inStream, Stream outStream = null); Stream DecompressGZip(this Stream inStream, Stream outStream = null);
从.NET2.0开始,就内置了Deflate压缩算法,这是很常见的一种数据压缩算法,HTTP常用它进行压缩,压缩比一般,但是压缩速度很好。上述字节数组和数据流的扩展就是对DeflateStream的简单封装,以兼容.NET2.0之上的所有应用(不同NFX版本的DeflateStream用法有所不同)。
而GZip则是一种数据格式,多了个头部,数据体部分还是Deflate压缩。因此,数据流压缩直接用Deflate算法,而压缩为文件时,则使用GZip,一般用gz后缀。
例如,XCode导出整表数据时,为了减小文件大小,会直接输出到用GZipStream包装的文件流。
文件压缩
PathHelper类扩展了文件和目录的压缩及解压缩。
void Extract(this FileInfo fi, String destDir, Boolean overwrite = false); void Compress(this FileInfo fi, String destFile); void Compress(this DirectoryInfo di, String destFile = null);
Extract把压缩文件解压缩到目标目录,支持覆盖已存在文件。一般用于压缩备份和数据恢复场合。
(注意:.zip后缀文件采用ZipFile类处理,其它后缀仅支持在Windows上调用7z处理,下同)
Compress把文件压缩到目标文件,一般用于压缩备份日志等文本文件,有很大的压缩比。
Compress另一个重载,把目录压缩到目标文件,一般用于压缩备份整个目录,如配置文件目录等。
ZipFile压缩
Zip压缩文件实现类ZipArchive,而ZipFile扩展了常用方法。
// 打开压缩文档 ZipArchive Open(String archiveFileName, ZipArchiveMode mode, Encoding entryNameEncoding = null); // 从目录创建压缩文档 void CreateFromDirectory(String sourceDirectoryName, String destinationArchiveFileName, CompressionLevel compressionLevel, Boolean includeBaseDirectory);
压缩文件:
using var zip = ZipFile.Open(destFile, ZipArchiveMode.Create); zip.CreateEntryFromFile(fi.FullName, fi.Name, CompressionLevel.Optimal);
解压缩文件:
using var zip = ZipFile.Open(fi.FullName, ZipArchiveMode.Read, null); var di = Directory.CreateDirectory(destDir); var fullName = di.FullName; foreach (var item in zip.Entries) { var fullPath = Path.GetFullPath(Path.Combine(fullName, item.FullName)); if (!fullPath.StartsWith(fullName, StringComparison.OrdinalIgnoreCase)) throw new IOException("IO_ExtractingResultsInOutside"); if (Path.GetFileName(fullPath).Length == 0) { if (item.Length != 0L) throw new IOException("IO_DirectoryNameWithData"); Directory.CreateDirectory(fullPath); } else { Directory.CreateDirectory(Path.GetDirectoryName(fullPath)); try { item.ExtractToFile(fullPath, overwrite); } catch { } } }
Zip文件本质上就是一个档案数据库,头部有目录,后面就是各个被压缩文件的数据。通过扩展方法或者构造函数拿到ZipArchive后,直接CreateEntry就可以加入要压缩的文件,或者遍历Entries集合就得到内部每个被压缩文件。
7z压缩
SevenZip类用于对7z.exe进行包装,在Windows上处理各种类型压缩文件,它拥有极高的压缩比,在某些维护性系统中具有无可比拟的优势。
SevenZip首先在附近目录查找7z.exe,然后在注册表查找安装路径,实在找不到就从X组件资源站下载 http://x.newlifex.com/7z_v16.04.zip 。