C# - 文件压缩
工作中刚刚完成一个xx监控服务的开发任务,才疏学浅,仅仅是简单的实现,现在对开发中遇到的几个问题做一下整理。
一个是利用XML文件记录任务信息,XML文件简洁清晰、生成和解析操作方便,但是会涉及到文件越来越大的情况:
另外一个是文件越来越大,占用存储空间,涉及压缩存储的问题,本文对文件压缩的几种方法作简单总结。
考虑最大压缩比,将文件压缩成 .7z 格式。
7z.exe
相关工具下载:http://www.cnblogs.com/rentiansheng/archive/2011/09/15/2177716.html
必须将7z.dll、7z.exe、7zFM.exe、7zG.exe放入到工程项目的执行目录下。
using SevenZip; // SevenZipCompressor public static void CompressWithSevenZipCompressor(string FilePath, string zipFilepath) { // 7z.dll不能直接引用,必须指定路径 SevenZipCompressor.SetLibraryPath("7z.dll"); var zip = new SevenZipCompressor(); zip.CompressionLevel = CompressionLevel.High; // 压缩比 zip.ArchiveFormat = OutArchiveFormat.SevenZip; // 压缩格式 // zip.CompressionMethod = SevenZip.CompressionMethod.Lzma; // 压缩算法 // zip.CompressionMode = SevenZip.CompressionMode.Create; // 压缩模式 // zip.ZipEncryptionMethod = SevenZip.ZipEncryptionMethod.Aes256; // 压缩加密算法 // 普通压缩方法:文件带有文件夹,使用不方便 zip.CompressFiles(zipFilepath, FilePath); // 字典集压缩方法:推荐 Dictionary<string, string> myDic = new Dictionary<string, string>(); myDic.Add(FileName, FilePath); zip.CompressFileDictionary(myDic, zipFilepath); }
注意其中几个问题:
- 路径最好不要包含空格;若包含空格,应该加引号:"\"" + strPath + "\""
- 解压缩中,-o表示输出目录,其与目录路径之间没有空格
- 解压既可以输出到当前目录,也可以输出到指定文件夹,只要更改 OutDirectory 即可
参考
SevenZipSharp.dll
SevenZipSharp是Codeplex的开源项目,使用7-zip的library,需要7z.dll和SevenZipSharp.dll,网上直接下载即可。
- SevenZipSharp.dll需要添加引用;
- 7z.dll无法直接引用,需要指定其路径
1 using SevenZip; 2 3 public static void CompressWithSevenZipCompressor(string FilePath, string zipFilepath) 4 { 5 // 7z.dll不能直接引用,必须指定路径 6 SevenZipCompressor.SetLibraryPath("7z.dll"); 7 var zip = new SevenZipCompressor(); 8 zip.CompressionLevel = CompressionLevel.High; // 压缩比 9 zip.ArchiveFormat = OutArchiveFormat.SevenZip; // 压缩格式 10 // zip.CompressionMethod = SevenZip.CompressionMethod.Lzma; // 压缩算法 11 // zip.CompressionMode = SevenZip.CompressionMode.Create; // 压缩模式 12 // zip.ZipEncryptionMethod = SevenZip.ZipEncryptionMethod.Aes256; // 压缩加密算法 13 14 15 // 普通压缩方法:文件带有文件夹,使用不方便 16 zip.CompressFiles(zipFilepath, FilePath); 17 // 字典集压缩方法:推荐 18 Dictionary<string, string> myDic = new Dictionary<string, string>(); 19 myDic.Add(FileName, FilePath); 20 zip.CompressFileDictionary(myDic, zipFilepath); 21 }
若压缩多个文件,传参 List<string> FilePaths 即可。
using SevenZip; // SevenZipCompressor public static void CompressWithSevenZipCompressor(string FilePath, string zipFilepath) { // 7z.dll不能直接引用,必须指定路径 SevenZipCompressor.SetLibraryPath("7z.dll"); var zip = new SevenZipCompressor(); zip.CompressionLevel = CompressionLevel.High; // 压缩比 zip.ArchiveFormat = OutArchiveFormat.SevenZip; // 压缩格式 // zip.CompressionMethod = SevenZip.CompressionMethod.Lzma; // 压缩算法 // zip.CompressionMode = SevenZip.CompressionMode.Create; // 压缩模式 // zip.ZipEncryptionMethod = SevenZip.ZipEncryptionMethod.Aes256; // 压缩加密算法 // 普通压缩方法:文件带有文件夹,使用不方便 zip.CompressFiles(zipFilepath, FilePath); // 字典集压缩方法:推荐 Dictionary<string, string> myDic = new Dictionary<string, string>(); myDic.Add(FileName, FilePath); zip.CompressFileDictionary(myDic, zipFilepath); }
本文只简单介绍上述2种方法,7z.exe方法压缩速度较快。
其他可参考:【原创】.NET开源压缩组件介绍与入门;
QuickLZ
Fast compression library for C, C# and Java,号称世界压缩速度最快的压缩库。
类库代码如下
/* DLL wrapper class for the QuickLZ 1.5.x DLL files 官网:http://www.quicklz.com/ */ public class QuickLZ { // The C library passes many integers through the C type size_t which is 32 or 64 bits on 32 or 64 bit // systems respectively. The C# type IntPtr has the same property but because IntPtr doesn't allow // arithmetic we cast to and from int on each reference. To pass constants use (IntPrt)1234. [DllImport("quicklz150_32_1.dll")] public static extern IntPtr qlz_compress(byte[] source, byte[] destination, IntPtr size, byte[] scratch); [DllImport("quicklz150_32_1.dll")] public static extern IntPtr qlz_decompress(byte[] source, byte[] destination, byte[] scratch); [DllImport("quicklz150_32_1.dll")] public static extern IntPtr qlz_size_compressed(byte[] source); [DllImport("quicklz150_32_1.dll")] public static extern IntPtr qlz_size_decompressed(byte[] source); [DllImport("quicklz150_32_1.dll")] public static extern int qlz_get_setting(int setting); private byte[] state_compress; private byte[] state_decompress; // 实例化 public QuickLZ() { state_compress = new byte[qlz_get_setting(1)]; if (QLZ_STREAMING_BUFFER == 0) state_decompress = state_compress; else state_decompress = new byte[qlz_get_setting(2)]; } // 压缩 public byte[] Compress(byte[] Source) { byte[] d = new byte[Source.Length + 400]; uint s; s = (uint)qlz_compress(Source, d, (IntPtr)Source.Length, state_compress); byte[] d2 = new byte[s]; System.Array.Copy(d, d2, s); return d2; } // 解压 public byte[] Decompress(byte[] Source) { byte[] d = new byte[(uint)qlz_size_decompressed(Source)]; uint s; s = (uint)qlz_decompress(Source, d, state_decompress); return d; } public uint SizeCompressed(byte[] Source) { return (uint)qlz_size_compressed(Source); } public uint SizeDecompressed(byte[] Source) { return (uint)qlz_size_decompressed(Source); } public uint QLZ_COMPRESSION_LEVEL { get { return (uint)qlz_get_setting(0); } } public uint QLZ_SCRATCH_COMPRESS { get { return (uint)qlz_get_setting(1); } } public uint QLZ_SCRATCH_DECOMPRESS { get { return (uint)qlz_get_setting(2); } } public uint QLZ_VERSION_MAJOR { get { return (uint)qlz_get_setting(7); } } public uint QLZ_VERSION_MINOR { get { return (uint)qlz_get_setting(8); } } public int QLZ_VERSION_REVISION { // negative means beta get { return (int)qlz_get_setting(9); } } public uint QLZ_STREAMING_BUFFER { get { return (uint)qlz_get_setting(3); } } public bool QLZ_MEMORY_SAFE { get { return qlz_get_setting(6) == 1 ? true : false; } } }
调用方式,需实例化对象
QuickLZ qlz = new QuickLZ();
具体参见官网:http://www.quicklz.com/
---
纵使山重水复,亦会柳暗花明
sunqh1991@163.com
欢迎关注,互相交流