转自:http://www.cnblogs.com/asxinyu/archive/2013/03/05/2943696.html
阅读目录
本博客所有文章分类的总目录:【总目录】本博客博文总目录-实时更新
本博客其他.NET开源项目文章目录:【目录】本博客其他.NET开源项目文章目录
1.前言
作为吉日嘎拉权限管理系统最早的一批学习版用户,学了不少东西,在群里面也结识了很多朋友,更重要的是闲余时间,大家都发布很多可靠的外包工作。这次也是由于吉日嘎拉发布了一个有关“压缩文件损坏检测”的外包任务,最早在2009年用C#很简单的使用过压缩组件,这次有了这个需求,才所以才深入研究一番,顺便有了这篇博客。
在日常项目开发过程中,操作Zip或者RAR压缩文件也是一件比较常见的事情。主要是打包文件,解压文件等等常规的操作,也相信很多人也用过.NET自带的GZip压缩。今天要给大家介绍的是一些开源的压缩组件的一些简单入门,由于压缩格式很多,效率也不一样,所以开源的东西还是很不错的,支持很全面。
还是老规矩,本文将对这篇文章中提到的相关组件及其源代码,文档或者官方案例打包,统一于3月6日上午11点左右发送,需要的留下邮箱,过期不候。当然,好的文章和资源还需要园友们的支持,如果对你有帮助,不要吝啬鼠标哦,你们的支持就是我原创的动力。
2.关于压缩格式和算法的基础
数据压缩是按照特定的编码机制用比未经编码少的数据比特(或者其它信息相关的单位)表示信息的过程。随着信息技术的高速发展,数据压缩的使用在网络时代越来越重要。对一些特殊的数据如相片、音频、视频的压缩算法也不同。我们今天说的压缩算法都是无损压缩,无损数据压缩指数据经过压缩后,信息不受损失,还能完全恢复到压缩前的原样。“无损”一词是相对于有损数据压缩,有损数据压缩只允许一个近似原始数据进行重建,以换取更好的压缩率。常见的无损压缩算法有LZW、ZIP、RAR、7-Zip等。详细看看几种主流的无损数据压缩格式:
ZIP文件格式是一种流行的数据压缩和文档储存的文件格式,原名Deflate。目前,ZIP格式属于几种主流的压缩格式之一,其竞争者包括RAR格式以及开放源码的7z格式。从性能上比较,RAR及7-Zip格式较ZIP格式压缩率较高,而7-Zip由于提供了免费的压缩工具而逐渐在更多的领域得到应用。该格式开放而且免费,越来越多的软件内嵌支持打开Zip文件。
RAR是一种专利文件格式,用于数据压缩与归档打包,RAR编码器一直是有专利的。所以这也就是为什么我们看到很多开源的压缩软件或者工具能够解压RAR,而不支持RAR打包的原因。RAR通常情况比ZIP压缩比高,但压缩/解压缩速度较慢。
7z是一种可以使用多种压缩算法进行数据压缩的档案格式。该格式最初被7-Zip实现并采用,但是这种档案格式是公有的,并且7-Zip软件本身亦在GNU宽通用公共许可证 (GNU LGPL)协议下开放源代码。7z格式的主要特色有:开源且模块化的组件结构(允许使用任何压缩,转换或加密算法);高压缩比率(使用不同的压缩算法会有不同的结果);支持超大文件;该格式的开发结构允许添加标准以外的压缩算法。
总结:总的来说,我还是比较喜欢7Zip格式,压缩率确实高很多,而且开源。但是如果实际项目由于历史原因等,需要采用Zip或者RAR的,也没办法,还是有很多开源的组件可供选择。
3.几种常见的.NET开源数据压缩组件
3.1 ZIP-DotNetZip
DotNetZip是.NET开源压缩组件中比较早的一个,我在2009年的时候给导师折腾一个小项目,就用到了,所以对其基本操作很熟悉。现在最新版本是1.9.1.8,很久没更新了,也很稳定。网址:http://dotnetzip.codeplex.com/ 。使用DotNetZip,可以很容易的创建、解压以及更新ZIP文件。官网有很多例子,以及介绍,篇幅比较长,就不去翻译了。简单使用,看下一节的使用例子就行了。
3.2 7Zip-SevenZipSharp
SevenZipSharp是.NET下开源的7-Zip格式操作组件,支持所有的7Zip格式。目前最新版本是2010年发布的0.64。由于7Zip的高压缩率以及开源特点,在新项目中使用是最好的选择。网址:http://sevenzipsharp.codeplex.com/ 。它支持的格式比上面多,如:7Zip,RAR,ZIP,Gzip,Cab,LZH等等。注意,除了引用这个组件之外,还需要加7z.dll文件拷贝到bin目录中,因为SevenZipSharp是对7z.dll的一个封装。7z.dll可以在官网http://7-zip.org/下载到,或者看我最后的资料下载,会打包进去的。
3.3 综合-SharpCompress
SharpCompress 也是.NET下开源的压缩文件操作组件。与上面2个不同的是,他支持的格式更多,如RAR,ZIP,Tar,7Zip等等。这个开源项目好像是去年才开始的,在其他几个开源的项目基础上发展而来,也包括了DotNetZip,Nunrar项目。当然对RAR也只是解压,上面提到了RAR是专利算法,所以不支持创建RAR文件。当然这个还支持很多其他的压缩格式,比如Tar、GZip等等,就不多说了,例子就用我们最常见的ZIP、RAR和7Zip。
3.4 关于调用WINRAR
在处理压缩文件时,还有一种常见的方法,就是使用WINRAR的命令行。网上有很多操作的例子,我也测试过,成功了。但不得不说,灵活性很差。肯定可以满足一小部分人的需求,但我认为这个方法的确不太好。所以在这里就不提倡了,毕竟有现成的更好的东西。为什么说这个WINRAR呢?主要是大家都知道WINRAR是收费的,RAR是专利算法,但其实WINRAR还是提供了免费的程序调用方式,就是UNRAR,在WINRAR的安装文件夹有一个UnrarSrc.txt的说明文件,打开它,里面有地址:www.rarlab.com。需要的自己去看,我找这个东西可花了不少时间,就是因为资料太少,所以也留个脚印吧。
4.基本入门使用教程
4.1 DotNetZip的基本使用
//创建压缩文件
using (ZipFile zip = new ZipFile())
{
//设置密码,也可以为每个文件单独设置密码
zip.Password= "123456!";
//添加文件
zip.AddFile("ReadMe.txt");
//添加目录
zip.AddDirectory(@"MyDocuments\ProjectX");
//设置备注信息
zip.Comment = "This is a demo";
//还可以设置压缩方式,编码等
//保存文件
zip.Save("Package.zip");
} //解压文件
using (ZipFile zip = ZipFile.Read("Demo.zip"))
{ //遍历zip文件中每一个文件对象,然后解压到指定目录
foreach (ZipEntry e in zip)
{
e.Extract(@"C:\test", true);
//若有密码,用下面这个方法
e.ExtractWithPassword(BaseDirectory, Password);
}
//也可以通过索引访问文件对象
//ZipEntry e = zip["MyReport.doc"];
}
当然这只是最简单的压缩和解压Zip文件的操作,还有更多功能可以操作Zip,比如移除文件,通过文件流来压缩和解压缩等等。可以看一下帮助文档,这里只是介绍最基本的功能。因为这次研究这个主要是为了检测错误的Zip文件,所以在这里,留一个疑问给大家:如何判断一个zip文件是否损坏?过一段时间会给大家一个思路,当然不是唯一的解决办法。
4.2 SevenZipSharp基本使用
这里只演示基本的使用,类库还有异常处理、文件流操作等。可以看帮助文档。
//初始化一个压缩器,这个对象一次可以压缩多个文件
SevenZipCompressor sc = new SevenZipCompressor();
//设置压缩格式,这里是枚举类型,可以选其他的
sc.ArchiveFormat = OutArchiveFormat.Zip;
//压缩模式,新创建还是追加,若是追加
sc.CompressionMode = CompressionMode.Create;
//设置压缩算法,也可以不设置,采用默认的
//可以使用ZipEncryptionMethod来设置每个文件的密码
sc.CompressionMethod = SevenZip.CompressionMethod.Default;
//单独压缩文件,CompressFilesEncrypted方法可以设置密码
//注意这里的文件路径,要写全称
sc.CompressFiles("test.zip", @"C:\X\a.txt", @"C:\X\b.txt");
//CompressDirectory 方法单独压缩目录
//CompressFileDictionary方法可以压缩文件或者目录,传入一个字典,会自动识别目录或者文件 //解压缩,可以在初始化的时候设置解压密码
SevenZipExtractor se = new SevenZipExtractor("test.zip");
foreach (var item in se.ArchiveFileNames)
{ //逐一解缩
se.BeginExtractFiles(@"C:\X", item);
}
//一次性全部解压
// se.BeginExtractArchive(@"C:\X");
4.3 SharpCompress基本使用
SharpCompress是在DotNetZip等开源项目的基础上发展起来的,因此其使用和DotNetZip很类似。这里给一个网址,上面有例子,大家自己去琢磨一下:例子链接
4.总结与资源
总结起来,我觉得DotNetZip使用最灵活,而SevenZipSharp与SharpCompress支持的格式多,而且7zip的压缩率很大,格式开源,使用的场合比较多。RAR格式尽量不要用吧,商业算法,非要使用,一般的类库都可以解压,但压缩可以用上面3.4节提到的UNRAR。可能也还有很多其他的开源组件,不足之处,还请大家指出。
下面是上面几个开源类库的网址以及相关使用资源:
DotNetZip :http://dotnetzip.codeplex.com/
SevenZipSharp :http://sevenzipsharp.codeplex.com/
SharpCompress:http://sharpcompress.codeplex.com/
解压工具类,注意使用nuget添加SevenZipSharp和7z包,7z.dll需要右键属性 始终复制
using SevenZip;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text; namespace Fisher361.Common
{
public class CompressHelper
{
/// <summary>
/// 解压压缩文件
/// </summary>
/// <param name="path">压缩文件路径</param>
/// <param name="decomPath">解压缩目录</param>
/// <param name="sync">是否异步</param>
public static void UnAll(string path, string decomPath, bool sync = false)
{
string ext = System.IO.Path.GetExtension(path).ToLower(); switch (ext)
{
case ".zip":
//解压zip
CompressHelper.UnRar(path, decomPath, sync);
break;
case ".rar":
//解压rar
CompressHelper.UnRar(path, decomPath, sync);
break;
case ".tar":
//解压rar
CompressHelper.UnRar(path, decomPath, sync);
break;
case ".7z":
//解压zip
CompressHelper.Un7z(path, decomPath, sync);
break;
case ".iso":
break;
default:
throw new System.Exception("不支持的格式!");
}
} /// <summary>
/// 解压zip压缩文件
/// </summary>
/// <param name="path">压缩文件路径</param>
/// <param name="decomPath">解压缩目录</param>
public static void UnZip(string path, string decomPath, bool sync = false)
{
try
{
SevenZipExtractor se = new SevenZipExtractor(path);
//一次性全部解压
if (sync)
{
se.BeginExtractArchive(decomPath);
}
else
{
se.ExtractArchive(decomPath);
}
}
catch (System.Exception ex)
{
throw ex;
}
} /// <summary>
/// 解压tar.gz/rar压缩文件
/// </summary>
/// <param name="path">压缩文件路径</param>
/// <param name="decomPath">解压缩目录</param>
public static void UnRar(string path, string decomPath, bool sync = false)
{
try
{
SevenZipExtractor se = new SevenZipExtractor(path);
//一次性全部解压
if (sync)
{
se.BeginExtractArchive(decomPath);
}
else
{
se.ExtractArchive(decomPath);
}
}
catch (System.Exception ex)
{
throw ex;
}
} /// <summary>
/// 解压7z压缩文件
/// </summary>
/// <param name="path">压缩文件路径</param>
/// <param name="decomPath">解压缩目录</param>
public static void Un7z(string path, string decomPath, bool sync = false)
{
try
{
SevenZipExtractor se = new SevenZipExtractor(path);
//一次性全部解压
if (sync)
{
se.BeginExtractArchive(decomPath);
}
else
{
se.ExtractArchive(decomPath);
}
}
catch (System.Exception ex)
{
throw ex;
}
}
}
}