Windows8 的开发已经如火如荼开始了,在 Windows8 中提供的 .NET Framework 已经更新到了 4.5 版,其中又增加了一些新的特性,对压缩文件的支持就是其中之一。
在 4.5 之前,处理压缩文件,我们经常需要使用第三方的类库 , 现在可以直接实现了。
1.准备工作
首先做一下准备工作,需要确保你使用 .NET 4.5 版,可以在项目的属性窗口中检查一下。
然后,引用必须的程序集。
程序集有两个:System.IO.Compression 和 System.IO.Compression.FileSystem.
类似于对文件和目录的操作,对于压缩文件也提供了两种方式:ZipArchive 和 ZipFile,分别对应两个新增加的类 ZipArchive 和 ZipFile。这两个类都定义在命名空间 System.IO.Compression 中。
为了后面演示方便,我们定义一个表示压缩文件路径的常量。
const string zipFilePath = @"..\..\Sample.zip";
2. 使用 ZipArchive
先看ZipArchive的使用。
2.1 创建压缩文件
创建一个空的压缩文件,使用 ZipArchiveMode.Create 创建参数。
// 创建 Zip 文件using (FileStream zipFileToOpen = new FileStream(zipFilePath, FileMode.Create))using (ZipArchive archive = new ZipArchive(zipFileToOpen, ZipArchiveMode.Create)){}
使用 WinRaR 打开压缩文件,可以看到里面没有文件。
2.2 创建并添加文件
通常,在创建的同时,我们就会加入一些文件,下面的例子中,我们将当前的执行程序文件本身加到压缩文件中。
// 创建并添加被压缩文件using (FileStream zipFileToOpen = new FileStream(zipFilePath, FileMode.Create))using (ZipArchive archive = new ZipArchive(zipFileToOpen, ZipArchiveMode.Create)){ System.Reflection.Assembly assemble = System.Reflection.Assembly.GetExecutingAssembly(); string path = assemble.Location; string filename = System.IO.Path.GetFileName(path); ZipArchiveEntry readMeEntry = archive.CreateEntry(filename); using (System.IO.Stream stream = readMeEntry.Open()) { byte[] bytes = System.IO.File.ReadAllBytes(path); stream.Write(bytes, 0, bytes.Length); }}
现在,打开压缩文件,可以看到文件已经被压缩进来了。
2.3 列出压缩文件内容
当然,也可以通过程序检查压缩文件的内容了。使用 Read 方式就可以了。
// 列出压缩压缩文件using (FileStream zipFileToOpen = new FileStream(zipFilePath, FileMode.Open))using (ZipArchive archive = new ZipArchive(zipFileToOpen, ZipArchiveMode.Read)){ foreach (var zipArchiveEntry in archive.Entries) Console.WriteLine( "FullName of the Zip Archive Entry: {0}", zipArchiveEntry.FullName );}
2.4 提取压缩文件
当然可以从压缩文件中提取被压缩的内容了。
// 读取其中一个文件的内容using (FileStream zipFileToOpen = new FileStream(zipFilePath, FileMode.Open))using (ZipArchive archive = new ZipArchive(zipFileToOpen, ZipArchiveMode.Read)){ // 解压某个文件 ZipArchiveEntry entry = archive.GetEntry("ZipArchiveSample.exe"); Console.WriteLine(entry.Name); using (System.IO.Stream stream = entry.Open()) { System.IO.Stream output = new FileStream("http://www.cnblogs.com/ZipArchiveSample.exe", FileMode.Create); int b = -1; while ((b = stream.ReadByte()) != -1) { output.WriteByte((byte) b); } output.Close(); }}
2.5 更新压缩文件
在压缩文件已经创建之后,还可以打开它,继续添加文件,这就称为更新了,使用 Update 模式。
// 向现有的压缩文件中添加文件using (FileStream zipFileToOpen = new FileStream(zipFilePath, FileMode.Open))using (ZipArchive archive = new ZipArchive(zipFileToOpen, ZipArchiveMode.Update)){ // 这里添加当前正在执行的程序文件本身 System.Reflection.Assembly assemble = System.Reflection.Assembly.GetExecutingAssembly(); string path = assemble.Location; string filename = System.IO.Path.GetFileName( path); ZipArchiveEntry readMeEntry = archive.CreateEntry( filename ); using (System.IO.Stream stream = readMeEntry.Open() ) { byte[] bytes = System.IO.File.ReadAllBytes(path); stream.Write(bytes, 0, bytes.Length); } foreach (var zipArchiveEntry in archive.Entries) Console.WriteLine( "FullName of the Zip Archive Entry: {0}", zipArchiveEntry.FullName );}
现在压缩文件中又增加了一个,这可以一个怪异的文件,同一个文件被在压缩文件中添加了两次!
3. 使用 ZipFile
除了上边的基本方法之外,还有一些简单的使用方法。这涉及到另外一个类:ZipFile。
3.1 创建空压缩文件
// 删除压缩文件System.IO.File.Delete(zipFilePath);// 使用 ZipFile 的静态方法创建压缩文件,要保证文件没有存在using (ZipArchive zipArchive = ZipFile.Open(zipFilePath, ZipArchiveMode.Create)){}
3.2 创建并添加文件
直接添加一个文件的方法。直接使用 CreateEntryFromFile 就可以了。
System.IO.File.Delete(zipFilePath);// 使用 CreateEntryFromFile 方法添加文件// 使用 ZipFile 的静态方法创建压缩文件using (ZipArchive zipArchive = ZipFile.Open(zipFilePath, ZipArchiveMode.Create)){ System.Reflection.Assembly assemble = System.Reflection.Assembly.GetExecutingAssembly(); string path = assemble.Location; string filename = System.IO.Path.GetFileName(path); zipArchive.CreateEntryFromFile(path, filename);}
3.3 解压文件
将压缩文件解压到指定的目录中。
// 解压文件ZipFile.ExtractToDirectory(zipFilePath, "../..");
3.4 压缩一个目录
还可以直接将一个目录中所有的文件都压缩到一个压缩文件中。
// 压缩指定目录中所有文件System.IO.File.Delete(zipFilePath);ZipFile.CreateFromDirectory(".", zipFilePath);
你是不是最喜欢这个方法?现在压缩文件中的文件更多了。
附录:
SharpZipLib 的下载地址: