序
这是《.NET开源项目的前世和今生系列》之一,如上一篇《.NET开源数据库的前世和今生》。这些系列是我对过去10年中了解的.NET开源项目的总结。
《.NET开源项目的前世和今生系列》的大概结构如下(假如我还有心思写下去的话):
- 《.NET开源数据库的前世和今生》 上、下
- 《.NET开源文档处理的前世和今生》:压缩、Office(Word/Excel/PPT/MAPI)、其它(PDF/RTF)
- 《.NET开源多媒体处理的前世和今生》:图像、图标、视频、音频、Flash等
- 《.NET开源基础库的前世和今生》:Queue、Schedule
- 《.NET开源网络访问的前世和今生》:Web服务器、爬虫、MSN、XMPP、IRC、NNTP、统计
- 《.NET开源系统交互与安全的前世和今生》:环境/进程/安全/认证
前言
开发行业很多开源的项目,历史我不在这里追溯,既然那么多有心有力的朋友分享了他们的成果,在遵循许可的情况下,我们拿来用就是了。当然,你可以写比开源的更好更适合自己的,但摆着现成的不用那可是罪过啊。不过选择开源项目需要考虑很多:1.项目的协议,会不会造成代码污染;2.项目的生命力,说不定明天作者就不干了,又或者作者过着逍遥自在的生活,几年都不更新一次,你自己接着开发?
正题
Zip
好吧,相信大部分人都知道.NET Zip Library #ziplib (SharpZipLib),这是SharpDevelop的之父Mike Krueger在写SharpDevelop的副产物。目的很单纯:就是想弄个纯c#的读写zip的,不想用InterOp。我之前说过,做开源项目的,多是重口味的。SharpZipLib使用非常广泛,几乎每个需要用到压缩文档的.NET程序都会选择它。它很优秀,确实,虽然在初期对中文支持不好。虽然它的“双性”许可比较让人糊涂。但有好事者反复在论坛上问SharpZipLib的许可,作者也坐不住了,在了那套首页特别说明了,LGPL,商业免费。早说嘛,程序员都喜欢瞎折腾。
既然SharpZipLib那么优秀,那为什么别人还写类似的呢?因为除了重口味,还有轻口味的需求:部分程序还是轻量级的,譬如我。一般需求就是:压缩、解压Zip文档,或者只是压缩、解压一个byte数组。在.NET 2.0之前的1.X时代,我们只能用:Interop + Zlib:#zlib - Modifying Archives。但有一些洁癖的,觉得额外用一个Win32的dll很不爽。所以便有了纯C#的ZLIB.NET。如果你只是想压缩byte数组:Better Than Zip Algorithm For Compressing In-Memory Data。在.NET 2.0,引入了System.IO.Compression.DeflateStream和System.IO.Compression.GZipStream。
如果你想压缩文档:ZipStorer - A Pure C# Class to Store Files in Zip,它还在这里弄了个项目:ZipStorer - A Pure C# Class to Store Files in Zip ,但有一个很要命的问题:它不支持压缩。当然还有支持压缩的:Encrypted Zipping of Files in C# and Java。
在.NET 3.x,微软的脑筋终于通了,引入了文档压缩:.NET Framework Zip / UnZip Tool Using the Packaging Namespace
重口味的,还有用J#自带的来弄的,如:Zip/Unzip using java.util.zip .net namespace and more、Zip and Unzip from a C# program using J# runtime 、Simple Application to Zip and UnZip files in C# using J#,也有用Windows系统的:Compress Zip files with Windows Shell API and C#
如果你纯粹要求一个足够强大的Zip文档压缩读写库,我建议你用DotNetZip Library 。它具备了ZIP的所有操作,也很弹性,谁用谁知道~
除了基本的文档压缩之外,还衍生出了开发项目的自动压缩,如:ZipStudio - A versatile Visual Studio add-in to zip up Visual Studio solutions and projects(项目:ZipStudio ) 、SolutionZipper: VS 2005 Add-in Cleans and Zips a Solution in One Step、Zip Solution 、SolZip、Backup Project Files to Gmail ,当然还有Extracting files from a remote ZIP archive这种特别的需求。当然,还有更特殊的癖好:.NET wrapper for Info-ZIP。
Cab
7Zip支持Cab,但我们或许不需要那么大的东西,我们只需要:Cabinet File (*.CAB) Compression and Extraction。很不幸,这也是Interop,而且还是用vc++ .net封装的。但我们也有Jim Mischel直接C#封装的:Accessing CAB Files from .NET 。
7Zip
SharpZipLib不支持RAR、ISO、7z、Arj、Cab、Rpm、Wim、Udf、Xar、Dmg等等,等等。天啊,原来SharpZipLib这么差的。。。如果你了解7Zip,其实这些就是7Zip所支持的格式。7Zip是用C写的,为Win32系统提供了COM接口。所以我们也只能用Interop了(我讨厌Interop!)。第一个吃螃蟹的是Eugene Sichkar,他写完 C# (.NET) Interface for 7-Zip Archive DLLs(项目:7zSharp ),继承了光荣的开源传统,不更新了。不过有另外一个牛人接过了他的衣钵:SevenZipSharp。当然,你还可以用纯C#读取7z格式:Port of 7zip archive reader to C#
RAR
你可以用RAR官方的SDK(UnRAR.dll)中包含的C#例子来读取,也可以用7Zip来读取RAR,但如果你需要纯C#的,这里有一个新鲜出炉的:NUnrar,第一版是不支持中文,而且文件名读取逻辑错误。我提出了之后,作者很快就修正了,可见部分外国的开源作者还是很闲的。。。除了读取,除非给你钱RAR的作者,否则你不能生成RAR文件,专利,有些时候让你很不爽;)
你想生成RAR又不想给钱?那可以:
StringBuilder command = new StringBuilder(" a -ep \"" + RARFile + "\" ");
for (int i = 0; i < Files.Count; i++)
{
command.Append("\"" + Files[i] + "\" ");
}
ProcessStartInfo info = new ProcessStartInfo(winRAR, command.ToString());
Process process = new Process();
process.StartInfo = info;
process.Start();
process.WaitForExit();
当然,你还得先判断一下winrar.exe是否存在。
Tar
SharpZipLib可以对Tar进行读写,另外,你还可以选择:tar-cs
ISO、VHD、VDI、 XVA、VMDK
SharpZipLib可以对ISO进行读写,你还可以用C# ISO image creator 来创建ISO,GomuIso9660 来读写。另外,还有更专业的:.NET DiscUtils ,除了ISO,它可以读写VHD, VDI, XVA, VMDK等各种虚拟机的文件!
MTF
MTF,就是Microsoft Tape Format,你可以用Reading MTF Backup Files来读取。
题外话
不要把压缩文件想得太复杂了,不同的格式虽有差异,但大体都是:一个总的文件头,记录多少个文件,偏移,大小等,然后是多个文件头(文件名、压缩前后大小、校验码等),最后就是压缩后的数据了。所以,主要差异还是文件头和压缩算法。
除了.zip,.cbz、.jar、.xap、Visual Studio的模板文件等等都是zip文件,只不过扩展名不一样罢了。同样,.cbr也是rar文件。