using
System;
using
System.IO;
using
System.IO.Compression;
namespace
Skyiv.Helper
...
{ static class Zip ... { public static void CompressFile( string sourceFile, string destinationFile) ... { if ( ! File.Exists(sourceFile)) throw new FileNotFoundException(); using (FileStream sourceStream = new FileStream(sourceFile, FileMode.Open, FileAccess.Read, FileShare.Read)) ... { byte [] buffer = new byte [sourceStream.Length]; int checkCounter = sourceStream.Read(buffer, 0 , buffer.Length); if (checkCounter != buffer.Length) throw new ApplicationException(); using (FileStream destinationStream = new FileStream(destinationFile, FileMode.OpenOrCreate, FileAccess.Write)) ... { using (GZipStream compressedStream = new GZipStream(destinationStream, CompressionMode.Compress, true )) ... { compressedStream.Write(buffer, 0 , buffer.Length); } } } } public static void DecompressFile( string sourceFile, string destinationFile) ... { if ( ! File.Exists( sourceFile)) throw new FileNotFoundException(); using (FileStream sourceStream = new FileStream(sourceFile, FileMode.Open)) ... { byte [] quartetBuffer = new byte [ 4 ]; int position = ( int )sourceStream.Length - 4 ; sourceStream.Position = position; sourceStream.Read(quartetBuffer, 0 , 4 ); sourceStream.Position = 0 ; int checkLength = BitConverter.ToInt32(quartetBuffer, 0 ); byte [] buffer = new byte [checkLength + 100 ]; using (GZipStream decompressedStream = new GZipStream(sourceStream, CompressionMode.Decompress, true )) ... { int total = 0 ; for ( int offset = 0 ; ; ) ... { int bytesRead = decompressedStream.Read(buffer, offset, 100 ); if (bytesRead == 0 ) break ; offset += bytesRead; total += bytesRead; } using (FileStream destinationStream = new FileStream(destinationFile, FileMode.Create)) ... { destinationStream.Write(buffer, 0 , total); destinationStream.Flush(); } } } } } }
using
System;
using
System.IO;
using
Skyiv.Helper;
namespace
Skyiv.Test
...
{ sealed class TestMain ... { static void Main() ... { try ... { string [] nameList = ... { " zip.zip " , " zip.cs " , " zip.txt " } ; Zip.CompressFile(nameList[ 1 ], nameList[ 0 ]); Zip.DecompressFile(nameList[ 0 ], nameList[ 2 ]); foreach ( string name in nameList) ... { Console.WriteLine( " {0,-11}: {1,11:N0} bytes " , name, new FileInfo(name).Length); } } catch (Exception ex) ... { Console.WriteLine(ex.Message); } } } }
运行结果如下:
zip.zip : 773 bytes
zip.cs : 2,196 bytes
zip.txt : 2,196 bytes
但是,如果有使用Zip.DecompressFile()方法去解压标准的ZIP文件,就会出现以下错误:
GZip 头中的幻数不正确。请确保正在传入 GZip 流。
此外,使用Zip.CompressFile()方法也不能将多个文件放入一个ZIP包。
看来,FCL2.0还是不能处理标准的ZIP文件,我目前是使用第三方的ICSharpZipLib来处理ZIP文件:
http://www.icsharpcode.net/OpenSource/SharpZipLib/Download.aspx