.NET Core 实战 [No.260~262] 压缩与解压缩
在 System.IO.Compression 命名空间下,.NET Core 框架已经封装了一组常用的类,用于对流进行压缩和解压缩。分别是
DeflateStream
ZipArchive
GZipStream
其中 DeflateStream
和 GZipStream
均继承自 System.IO.Stream 类。
DeflateStream
DeflateStream
类采用 Deflate 压缩标准算法,属于 huffman 编码的增强版。框架内部默认通过 zlib 实现 DeflateStream
类。
csharp
string inputFilePath = "input-data.json";
string compressedFilePath = "compressed-data.deflate";
string decompressedFilePath = "decompressed-data.json";
// 压缩文件
using (FileStream instream = new FileStream(inputFilePath, FileMode.Open))
using (FileStream outstream = new FileStream(compressedFilePath, FileMode.Create))
using (DeflateStream defstream = new DeflateStream(outstream, CompressionLevel.Optimal))
{
instream.CopyTo(defstream);
}
// 解压缩文件
using (FileStream outstream = new FileStream(compressedFilePath, FileMode.Open))
using (DeflateStream defstream = new DeflateStream(outstream, CompressionMode.Decompress))
using (FileStream dcstream = new FileStream(decompressedFilePath, FileMode.Create))
{
defstream.CopyTo(dcstream);
}
// 打印各个文件的大小
FileInfo f1 = new FileInfo(inputFilePath);
FileInfo f2 = new FileInfo(compressedFilePath);
FileInfo f3 = new FileInfo(decompressedFilePath);
Console.WriteLine($"压缩前文件大小:{f1.Length}");
Console.WriteLine($"压缩后文件大小:{f2.Length}");
Console.WriteLine($"解压后文件大小:{f3.Length}");
运行后会输出类似如下的内容。
txt
压缩前文件大小:175988
压缩后文件大小:11311
解压后文件大小:175988
注意: 并非所有文件都能产生较高的压缩比,某些特殊文件在压缩后反而会增大,但增大的幅度较小。
ZipArchive
ZipArchive
类支持对 zip 压缩文档的基本管理,压缩文件中的每个文件(实体)由 ZipArchiveEntry
进行维护。
在下面的示例中,创建了一个压缩文件并写入了 3 个文本文件,最后解压文件到项目根目录。
csharp
string zipFilePath = "demo-data.zip";
// 创建压缩文件,并写入内容
using (FileStream outfs = File.Create(zipFilePath))
using (ZipArchive zip = new ZipArchive(outfs, ZipArchiveMode.Create))
{
// 第一个文件
ZipArchiveEntry et1 = zip.CreateEntry("docs/doc1.txt");
using (Stream stream = et1.Open())
using (StreamWriter writer = new StreamWriter(stream))
{
writer.Write("示例文档 A");
}
// 第二个文件
ZipArchiveEntry et2 = zip.CreateEntry("docs/doc2.txt");
using (Stream stream = et2.Open())
using (StreamWriter writer = new StreamWriter(stream))
{
writer.Write("示例文档 B");
}
// 第三个文件
ZipArchiveEntry et3 = zip.CreateEntry("docs/doc3.txt");
using (Stream stream = et3.Open())
using (StreamWriter writer = new StreamWriter(stream))
{
writer.Write("示例文档 C");
}
}
// 解压文件
using (FileStream instream = File.OpenRead(zipFilePath))
using (ZipArchive zip = new ZipArchive(instream))
{
foreach (var et in zip.Entries)
{
// et.Name 属性仅包含文件名
// et.FullName 属性包含目录结构
using (Stream stream = et.Open())
using (FileStream fsout = File.Create(et.Name))
{
stream.CopyTo(fsout);
}
}
}
GZipStream
GZIP(全称 GUNzip)用于 Unix 系统的文件压缩,文件后缀为 .gz 。
.NET Core 框架以 GZipStream
类封装 GZip 算法相关功能,使用方法同 DeflateStream
相同。
csharp
string inFilePath = "input-data.json";
string outFileName = "demo.gz";
string unzipFileName = "unzip-data.json";
// 压缩文件
using (FileStream fsIn = File.OpenRead(inFilePath))
using (FileStream fsOut = File.Create(outFileName))
using (GZipStream gz = new GZipStream(fsOut, CompressionMode.Compress))
{
fsIn.CopyTo(gz);
}
// 解压缩文件
using (FileStream fsOut = File.OpenRead(outFileName))
using (GZipStream gz = new GZipStream(fsOut, CompressionMode.Decompress))
using (FileStream fsUz = File.Create(unzipFileName))
{
gz.CopyTo(fsUz);
}
// 打印各个文件的大小
FileInfo f1 = new FileInfo(inFilePath);
FileInfo f2 = new FileInfo(outFileName);
FileInfo f3 = new FileInfo(unzipFileName);
Console.WriteLine($"压缩前文件大小:{f1.Length}");
Console.WriteLine($"压缩后文件大小:{f2.Length}");
Console.WriteLine($"解压后文件大小:{f3.Length}");
运行结果如下:
txt
压缩前文件大小:175988
压缩后文件大小:11329
解压后文件大小:175988
参考:《.NET Core 实战:手把手教你掌握 380 个精彩案例》 -- 周家安 著