【IT168技术文档】
以前做项目的时候,需要提供文件压缩功能。当时是使用了一个开源的类库,名为ZipLib,使用起来还是很方便的。我还在自己的英文博客上post了一篇文章《ZipLib Works Well! 》也许是看到了这个功能的必要性,在.Net 2.0中,微软在System.IO中新增了System.IO.Compression命名空间,提供了压缩功能的相关类GZipStream。
这个类的使用与一般的文件流使用差不多。我没有分析其内部实现,但猜测应该还是采用Decorator模式对Stream进行了装饰,从中应用了 Compression算法。它通过Write()方法,将buffer里面的内容写到另一个文件流中,例如源文件为sourceFile,压缩后的文件为targetFile,则方法为:
在使用GZipStream时,需要添加引用:byte[] buffer = null; FileStream sourceStream = null; FileStream targetStream = null; GZipStream compressedStream = null; sourceStream = new FileStream(sourceFile,FileMode.Open,FileAccess.Read,FileShare.Read); buffer = new byte[sourceStream.Length]; sourceStream.Read(buffer,0,buffer.Length); targetStream = new FileStream(targetFile,FileMode.OpenOrCreate,FileAccess.Write); //将CompressedStream指向targetStream; compressedStream = new GZipStream(targetStream,CompressionMode.Compress,true); compressStream.Write(buffer,0,buffer.Length);
解压缩与前面的方法差不多,仍然使用GZipStream文件流:using System.IO; using System.IO.Compression;
// Read in the compressed source stream sourceStream = new FileStream ( sourceFile, FileMode.Open ); // Create a compression stream pointing to the destiantion stream decompressedStream = new GZipStream ( sourceStream, CompressionMode.Decompress, true ); // Read the footer to determine the length of the destiantion file 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]; int offset = 0; int total = 0; // Read the compressed data into the buffer while ( true ) { int bytesRead = decompressedStream.Read ( buffer, offset, 100 ); if ( bytesRead == 0 ) break; offset += bytesRead; total += bytesRead; } // Now write everything to the destination file destinationStream = new FileStream ( destinationFile, FileMode.Create ); destinationStream.Write ( buffer, 0, total ); // and flush everyhting to clean out the buffer destinationStream.Flush ( );