1 /// <summary> 2 /// 壓縮文件 FNameArry 為客戶端傳回來的文件列表:文件名數組,壓縮包的名稱strZipName 3 /// </summary> 4 /// <param name="FNameArry">文件名數組</param> 5 /// <param name="strZipName">壓縮包的名稱</param> 6 public void ZipFile(string[] FNameArry string strZipName) 7 { 8 9 10 if (strZipName.Length != 0) //壓縮包名稱不為空 11 { 12 ZipOutputStream u = new ZipOutputStream(File.Create(FileDir + strZipName)); //新建壓縮文件流 “ZipOutputStream” 13 for (int i = 0; i < FNameArry.Length; i++) 14 { 15 if (FNameArry[i] != "") //分離出來的文件名不為空 16 { 17 this.AddZipEntry(FNameArry[i] u out u); //向壓縮文件流加入內容 18 } 19 } 20 u.Finish(); // 結束壓縮 21 u.Close(); 22 } 23 } 24 25 26 27 28 29 30 //添加壓縮項目:p 為需壓縮的文件或文件夾; u 為現有的源ZipOutputStream; out j為已添加“ZipEntry”的“ZipOutputStream” 31 public void AddZipEntry(string p ZipOutputStream u out ZipOutputStream j) 32 { 33 string s = FileDir + p; 34 35 36 if (Directory.Exists(s)) //文件夾的處理 37 { 38 DirectoryInfo di = new DirectoryInfo(s); 39 40 41 //***********以下內容是修訂后添加的*********** 42 43 44 if (di.GetDirectories().Length <= 0) //沒有子目錄 45 { 46 ZipEntry z = new ZipEntry(p + "/"); //末尾“/”用於文件夾的標記 47 u.PutNextEntry(z); 48 } 49 50 51 //***************以上內容是修訂后添加的*************** 52 53 54 55 56 foreach (DirectoryInfo tem in di.GetDirectories()) //獲取子目錄 57 { 58 ZipEntry z = new ZipEntry(this.ShortDir(tem.FullName) + "/"); //末尾“/”用於文件夾的標記 59 u.PutNextEntry(z); //此句不可少,否則空目錄不會被添加 60 s = this.ShortDir(tem.FullName); 61 this.AddZipEntry(s u out u); //遞歸 62 } 63 foreach (FileInfo temp in di.GetFiles()) //獲取此目錄的文件 64 { 65 s = this.ShortDir(temp.FullName); 66 this.AddZipEntry(s u out u); //遞歸 67 } 68 } 69 else if (File.Exists(s)) //文件的處理 70 { 71 u.SetLevel(9); //壓縮等級 72 FileStream f = File.OpenRead(s); 73 byte[] b = new byte[f.Length]; 74 f.Read(b 0 b.Length); //將文件流加入緩沖字節中 75 ZipEntry z = new ZipEntry(this.ShortDir(s)); 76 u.PutNextEntry(z); //為壓縮文件流提供一個容器 77 u.Write(b 0 b.Length); //寫入字節 78 f.Close(); 79 } 80 j = u; //返回已添加數據的“ZipOutputStream” 81 } 82 83 84 85 86 87 88 89 90 /// <summary> 91 /// 解壓 92 /// </summary> 93 /// <param name="FNameArry">文件名參數列表</param> 94 public void UnZipFile(string[] FNameArry) //解壓縮 95 { 96 int i2 = 0; //防止名稱沖突的參數 97 for (int j = 0; j < FNameArry.Length; j++) 98 { 99 if (FNameArry[j] != "") 100 { 101 string un_time = System.DateTime.Now.ToShortDateString() + "-" + System.DateTime.Now.Hour.ToString() + "-" + System.DateTime.Now.Minute.ToString() + "-" + (System.DateTime.Now.Second + i2).ToString(); 102 string un_dir = FileDir + "Unzip-" + un_time; 103 Directory.CreateDirectory(un_dir); //創建以解壓時間為名稱的文件夾 104 ZipInputStream f = new ZipInputStream(File.OpenRead(FileDir + FNameArry[j])); //讀取壓縮文件,並用此文件流新建 “ZipInputStream”對象 105 106 107 A: ZipEntry zp = f.GetNextEntry(); //獲取解壓文件流中的項目。 另注(我的理解):在壓縮包里每個文件都以“ZipEntry”形式存在,其中包括存放文件的目錄信息。如果空目錄被壓縮,該目錄下將出現一個名稱為空、大小為 0 、“Crc”屬性為 00000000 的“文件”。此文件只是個標記,不會被解壓。 108 109 110 while (zp != null) 111 { 112 string FNameArry2; 113 if (zp.Name.IndexOf("/") >= 0) //獲取文件的目錄信息 114 { 115 int tmp1 = zp.Name.LastIndexOf("/"); 116 FNameArry2 = zp.Name.Substring(0 tmp1); 117 Directory.CreateDirectory(un_dir + "/" + FNameArry2 + "/"); //必須先創建目錄,否則解壓失敗 --- (A) 關系到下面的步驟(B) 118 } 119 if (!zp.IsDirectory && zp.Crc != 00000000L) //此“ZipEntry”不是“標記文件” 120 { 121 int i = 2048; 122 byte[] b = new byte[i]; //每次緩沖 2048 字節 123 FileStream s = File.Create(un_dir + "/" + zp.Name); //(B)-新建文件流 124 while (true) //持續讀取字節,直到一個“ZipEntry”字節讀完 125 { 126 i = f.Read(b 0 b.Length); //讀取“ZipEntry”中的字節 127 if (i > 0) 128 { 129 s.Write(b 0 i); //將字節寫入新建的文件流 130 } 131 else 132 { 133 break; //讀取的字節為 0 ,跳出循環 134 } 135 } 136 s.Close(); 137 } 138 goto A; //進入下一個“ZipEntry” 139 } 140 f.Close(); 141 i2++; 142 } 143 } 144 }