C# 压缩、解压缩
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 }
有道无术,术尚可求,有术无道,止于术