核心库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