C# ISharpZipLib 压缩/解压缩zip文件
SharpZipLib: recursively zip/unzip directory structure001 // Project: Salient 002 // http://salient.codeplex.com 003 // 004 // Copyright 2010, Sky Sanders <sky at skysanders.net> 005 // Dual licensed under the MIT or GPL Version 2 licenses. 007 // 008 // Date: May 24 2010 009 010 #region 011 012 using System; 013 using System.Collections.Generic; 014 using System.IO; 015 using System.Linq; 016 using ICSharpCode.SharpZipLib.Zip; 017 018 #endregion 019 020 namespace Salient.IO.Compression 021 { 022 public static class DirectoryCompression 023 { 024 public static void CompressDirectory( this Stream target, string sourcePath, 025 Func< string , bool > excludeFromCompression) 026 { 027 sourcePath = Path.GetFullPath(sourcePath); 028 029 string parentDirectory = Path.GetDirectoryName(sourcePath); 030 031 int trimOffset = ( string .IsNullOrEmpty(parentDirectory) 032 ? Path.GetPathRoot(sourcePath).Length 033 : parentDirectory.Length); 034 035 036 List< string > fileSystemEntries = new List< string >(); 037 038 fileSystemEntries 039 .AddRange(Directory.GetDirectories(sourcePath, "*" , SearchOption.AllDirectories) 040 .Select(d => d + "\\" )); 041 042 fileSystemEntries 043 .AddRange(Directory.GetFiles(sourcePath, "*" , SearchOption.AllDirectories)); 044 045 046 using (ZipOutputStream compressor = new ZipOutputStream(target)) 047 { 048 compressor.SetLevel(9); 049 050 foreach ( string filePath in fileSystemEntries) 051 { 052 if (excludeFromCompression(filePath)) 053 { 054 continue ; 055 } 056 057 compressor.PutNextEntry( new ZipEntry(filePath.Substring(trimOffset))); 058 059 if (filePath.EndsWith( @"\" )) 060 { 061 continue ; 062 } 063 064 byte [] data = new byte [2048]; 065 066 using (FileStream input = File.OpenRead(filePath)) 067 { 068 int bytesRead; 069 070 while ((bytesRead = input.Read(data, 0, data.Length)) > 0) 071 { 072 compressor.Write(data, 0, bytesRead); 073 } 074 } 075 } 076 077 compressor.Finish(); 078 } 079 } 080 081 082 public static void DecompressToDirectory( this Stream source, string targetPath, string pwd, 083 Func< string , bool > excludeFromDecompression) 084 { 085 targetPath = Path.GetFullPath(targetPath); 086 087 using (ZipInputStream decompressor = new ZipInputStream(source)) 088 { 089 if (! string .IsNullOrEmpty(pwd)) 090 { 091 decompressor.Password = pwd; 092 } 093 094 ZipEntry entry; 095 096 while ((entry = decompressor.GetNextEntry()) != null ) 097 { 098 if (excludeFromDecompression(entry.Name)) 099 { 100 continue ; 101 } 102 103 string filePath = Path.Combine(targetPath, entry.Name); 104 105 string directoryPath = Path.GetDirectoryName(filePath); 106 107 108 if (! string .IsNullOrEmpty(directoryPath) && !Directory.Exists(directoryPath)) 109 { 110 Directory.CreateDirectory(directoryPath); 111 } 112 113 if (entry.IsDirectory) 114 { 115 continue ; 116 } 117 118 byte [] data = new byte [2048]; 119 using (FileStream streamWriter = File.Create(filePath)) 120 { 121 int bytesRead; 122 while ((bytesRead = decompressor.Read(data, 0, data.Length)) > 0) 123 { 124 streamWriter.Write(data, 0, bytesRead); 125 } 126 } 127 } 128 } 129 } 130 } 131 }
Usage
01 using System; 02 using System.IO; 03 using NUnit.Framework; 04 using Salient.IO.Compression; 05 06 namespace CoreFiveConnector.Tests 07 { 08 [TestFixture] 09 public class Class1 10 { 11 [Test] 12 public void Test() 13 { 14 Func< string , bool > excludeFromCompression = path => { return false ; }; 15 16 MemoryStream compressed = new MemoryStream(); 17 18 19 compressed.CompressDirectory( "c:\\Temp" , excludeFromCompression); 20 21 22 // sharpzip closes the target so we need to create a new seekable stream 23 MemoryStream compressed2 = new MemoryStream(compressed.ToArray()); 24 25 Func< string , bool > excludeFromDecompression = path => { return false ; }; 26 27 compressed2.DecompressToDirectory( "c:\\Temp2" , null , excludeFromDecompression); 28 } 29 } 30 } |