c#壓縮和解壓縮檔案 使用SharpZip壓縮與解壓縮的實戰經驗2007-08-17 09:39 首先,在 http://www.icsharpcode.net/OpenSource/SharpZipLib/Default.aspx 下載源碼,找到“ZipConstants.cs”修改public static string ConvertToString(byte[] data){ return Encoding.GetEncoding("gb2312").GetString(data, 0, data.Length); //return Encoding.ASCII.GetString(data,0, data.Length);} public static byte[] ConvertToArray(string str){ return Encoding.GetEncoding("gb2312").GetBytes(str); //return Encoding.ASCII.GetBytes(str);}如此就可支援中文名稱了以下是我寫的壓縮與解壓縮的代碼:using System;using System.Collections;using System.ComponentModel;using System.Data;using System.Drawing;using System.Web;using System.Web.SessionState;using System.Web.UI;using System.Web.UI.WebControls;using System.Web.UI.HtmlControls;using ICSharpCode.SharpZipLib.Zip;namespace OA{ /// <summary> /// WebForm1 的摘要說明。 /// </summary> public class WebForm1 : System.Web.UI.Page { public string ServerDir; private void Page_Load(object sender, System.EventArgs e) { // 在此處放置使用者代碼以初始化頁面 this.ServerDir = Page.MapPath("."); this.ZipFile("01.txt*02.txt*000.zip"); //只是樣本,具體的大家自己去實現 this.ZipFile("01.txt*02.txt*001.zip"); this.UnZipFile("000.zip*001.zip"); } public string ShortDir(string s) { //將檔案的絕對路徑轉為相對路徑 string d=s.Replace(ServerDir,""); return d; } //壓縮檔 p 為用戶端傳回來的檔案清單:檔案名稱+壓縮包的名稱 public void ZipFile(string p) { string[] tmp = p.Split(new char[]{'*'}); //分離檔案清單 if(tmp[tmp.Length-1]!="") //壓縮包名稱不為空白 { ZipOutputStream u = new ZipOutputStream(File.Create(ServerDir+tmp[tmp.Length-1])); //建立壓縮檔流 “ZipOutputStream” for(int i =0;i<tmp.Length-1;i++) { if(tmp[i]!="") //分離出來的檔案名稱不為空白 { this.AddZipEntry(tmp[i],u,out u); //向壓縮檔流加入內容 } } u.Finish(); // 結束壓縮 u.Close(); } } //添加壓縮項目:p 為需壓縮的檔案或檔案夾; u 為現有的源ZipOutputStream; out j為已添加“ZipEntry”的“ZipOutputStream” public void AddZipEntry(string p,ZipOutputStream u,out ZipOutputStream j) { string s =ServerDir+p; if(Directory.Exists(s)) //檔案夾的處理 { DirectoryInfo di = new DirectoryInfo(s); //***********以下內容是修訂後添加的*********** if(di.GetDirectories().Length<=0) //沒有子目錄 { ZipEntry z = new ZipEntry(p+""""); //末尾“""”用於檔案夾的標記 u.PutNextEntry(z); } //***************以上內容是修訂後添加的*************** foreach(DirectoryInfo tem in di.GetDirectories()) //擷取子目錄 { ZipEntry z = new ZipEntry(this.ShortDir(tem.FullName)+""""); //末尾“""”用於檔案夾的標記 u.PutNextEntry(z); //此句不可少,否則空目錄不會被添加 s = this.ShortDir(tem.FullName); this.AddZipEntry(s,u,out u); //遞迴 } foreach(FileInfo temp in di.GetFiles()) //擷取此目錄的檔案 { s = this.ShortDir(temp.FullName); this.AddZipEntry(s,u,out u); //遞迴 } } else if(File.Exists(s)) //檔案的處理 { u.SetLevel(9); //壓縮等級 FileStream f = File.OpenRead(s); byte[] b = new byte[f.Length]; f.Read(b,0,b.Length); //將檔案流加入緩衝位元組中 ZipEntry z = new ZipEntry(this.ShortDir(s)); u.PutNextEntry(z); //為壓縮檔流提供一個容器 u.Write(b,0,b.Length); //寫入位元組 f.Close(); } j=u; //返回已添加資料的“ZipOutputStream” } public void UnZipFile(string p) //解壓縮 { string[] un_tmp = p.Split(new char[]{'*'}); int i2=0; //防止名稱衝突的參數 for(int j=0;j<un_tmp.Length;j++) { if(un_tmp[j]!="") { string un_time=System.DateTime.Now.ToShortDateString()+"-"+System.DateTime.Now.Hour.ToString()+"-"+System.DateTime.Now.Minute.ToString()+"-"+(System.DateTime.Now.Second+i2).ToString(); string un_dir =ServerDir+"Unzip-"+un_time; Directory.CreateDirectory(un_dir); //建立以解壓時間為名稱的檔案夾 ZipInputStream f = new ZipInputStream(File.OpenRead(ServerDir+un_tmp[j])); //讀取壓縮檔,並用此檔案流建立 “ZipInputStream”對象 A: ZipEntry zp = f.GetNextEntry(); //擷取解壓檔案流中的項目。 另注(我的理解):在壓縮包裡每個檔案都以“ZipEntry”形式存在,其中包括存放檔案的目錄資訊。如果空目錄被壓縮,該目錄下將出現一個名稱為空白、大小為 0 、“Crc”屬性為 00000000 的“檔案”。此檔案只是個標記,不會被解壓。 while(zp!=null) { string un_tmp2; if(zp.Name.IndexOf("""")>=0) //擷取檔案的目錄資訊 { int tmp1 = zp.Name.LastIndexOf(""""); un_tmp2 = zp.Name.Substring(0,tmp1); Directory.CreateDirectory(un_dir+""""+un_tmp2+""""); //必須先建立目錄,否則解壓失敗 --- (A) 關係到下面的步驟(B) } if(!zp.IsDirectory&&zp.Crc!=00000000L) //此“ZipEntry”不是“標記檔案” { int i =2048; byte[] b = new byte[i]; //每次緩衝 2048 位元組 FileStream s= File.Create(un_dir+""""+zp.Name); //(B)-建立檔案流 while(true) //持續讀取位元組,直到一個“ZipEntry”位元組讀完 { i = f.Read(b,0,b.Length); //讀取“ZipEntry”中的位元組 if(i>0) { s.Write(b,0,i); //將位元組寫入建立的檔案流 } else { break; //讀取的位元組為 0 ,跳出迴圈 } } s.Close(); } goto A; //進入下一個“ZipEntry” } f.Close(); i2++; } } } }}