项目功能:文件夹压缩 分享
近期做了一个项目,由于客户服务器上的数据比较庞大,客户要求将服务器上某些数据进行压缩要求文件带附件功能都压缩下载下来。
实现步骤:
1 using System; 2 using System.IO; 3 using ICSharpCode.SharpZipLib.Zip; 4 5 namespace Beinet.cn.Common 6 { 7 /// <summary> 8 /// 压缩解压缩类 9 /// </summary> 10 public class ZipHelper 11 { 12 #region 压缩方法 13 /// <summary> 14 /// 压缩指定的文件列表 15 /// </summary> 16 /// <param name="zipFilePath">要压缩到的文件路径名</param> 17 /// <param name="files">要被压缩的文件列表</param> 18 public static void ZipFiles(string zipFilePath, params string[] files) 19 { 20 if (files == null || files.Length == 0) 21 throw new ArgumentException("文件列表不能为空", "files"); 22 if (string.IsNullOrEmpty(zipFilePath)) 23 zipFilePath = Path.GetFileName(files[0]) + ".zip"; 24 25 using (ZipOutputStream zos = new ZipOutputStream(File.Create(zipFilePath))) 26 { 27 foreach (string file in files) 28 { 29 // GetDirectoryName,是用于把文件名中不需要压缩的路径替换掉,避免压缩包里出现C:这样的目录结构 30 string filename = Path.GetFullPath(file); // 避免出现c:\\//a.txt这样的多斜杠的路径,造成压缩路径显示错误 31 AddFileEntry(zos, filename, Path.GetDirectoryName(filename)); 32 } 33 zos.Close(); 34 } 35 } 36 37 /// <summary> 38 /// 压缩指定的目录列表 39 /// </summary> 40 /// <param name="zipFilePath">要压缩到的文件路径名</param> 41 /// <param name="dirs">要被压缩的目录列表</param> 42 public static void ZipDirs(string zipFilePath, params string[] dirs) 43 { 44 if (dirs == null || dirs.Length == 0) 45 throw new ArgumentException("目录列表不能为空", "dirs"); 46 if (string.IsNullOrEmpty(zipFilePath)) 47 zipFilePath = Path.GetFileName(dirs[0]) + ".zip"; 48 49 using (ZipOutputStream zos = new ZipOutputStream(File.Create(zipFilePath))) 50 { 51 foreach (string dir in dirs) 52 { 53 string dirname = Path.GetFullPath(dir); // 避免出现c:\\//abc这样的多斜杠的路径,造成压缩路径显示错误 54 AddDirEntry(zos, dirname, Path.GetDirectoryName(dirname)); 55 } 56 } 57 } 58 59 /// <summary> 60 /// 往已存在的压缩文件里添加指定的文件列表,压缩文件不存在时,新建 61 /// </summary> 62 /// <param name="zipFilePath">要压缩到的文件路径名</param> 63 /// <param name="files">要被压缩的文件列表</param> 64 public static void AddFiles(string zipFilePath, params string[] files) 65 { 66 if (string.IsNullOrEmpty(zipFilePath)) 67 zipFilePath = Path.GetFileName(files[0]) + ".zip"; 68 69 if (!File.Exists(zipFilePath)) 70 { 71 using (ZipOutputStream s = new ZipOutputStream(File.Create(zipFilePath))) 72 { 73 s.Finish(); 74 s.Close(); 75 } 76 } 77 using (ZipFile zip = new ZipFile(zipFilePath)) 78 { 79 zip.BeginUpdate(); 80 //zip.IsStreamOwner = false; 81 foreach (string file in files) 82 { 83 zip.Add(file); 84 } 85 zip.CommitUpdate(); 86 zip.Close(); 87 } 88 } 89 90 /// <summary> 91 /// 把目录加入压缩包,返回压缩的目录和文件数 92 /// </summary> 93 /// <param name="zos"></param> 94 /// <param name="dir"></param> 95 /// <param name="rootDir">用于把文件名中不需要压缩的路径替换掉,避免压缩包里出现C:这样的目录结构</param> 96 private static int AddDirEntry(ZipOutputStream zos, string dir, string rootDir) 97 { 98 string[] dirs = Directory.GetDirectories(dir); 99 string[] files = Directory.GetFiles(dir); 100 int ret = files.Length + dirs.Length; 101 foreach (string subdir in dirs) 102 { 103 int tmp = AddDirEntry(zos, subdir, rootDir); 104 if (tmp == 0) 105 { 106 string strEntryName = subdir.Replace(rootDir, ""); 107 ZipEntry entry = new ZipEntry(strEntryName + "\\_"); 108 zos.PutNextEntry(entry); 109 } 110 ret += tmp; 111 } 112 foreach (string file in files) 113 { 114 AddFileEntry(zos, file, rootDir); 115 } 116 return ret; 117 } 118 119 /// <summary> 120 /// 把文件加入压缩包 121 /// </summary> 122 /// <param name="zos"></param> 123 /// <param name="file"></param> 124 /// <param name="rootDir">用于把文件名中不需要压缩的路径替换掉,避免压缩包里出现C:这样的目录结构</param> 125 private static void AddFileEntry(ZipOutputStream zos, string file, string rootDir) 126 { 127 //rootDir = Regex.Replace(rootDir, @"[/\\]+", @"\");// 把多个斜杠替换为一个 128 //file = Regex.Replace(file, @"[/\\]+", @"\");// 把多个斜杠替换为一个 129 if (!rootDir.EndsWith(@"\")) 130 rootDir += @"\"; 131 using (FileStream fs = File.OpenRead(file)) 132 { 133 string strEntryName = file.Replace(rootDir, ""); 134 ZipEntry entry = new ZipEntry(strEntryName); 135 zos.PutNextEntry(entry); 136 int size = 1024; 137 byte[] array = new byte[size]; 138 while (fs.Position < fs.Length) 139 { 140 int length = fs.Read(array, 0, size); 141 zos.Write(array, 0, length); 142 } 143 fs.Close(); 144 } 145 } 146 147 /* 148 /// <summary> 149 /// 分段压缩方法,避免压缩超过150M的文件时,机器响应慢,暂时未用 150 /// </summary> 151 /// <param name="path"></param> 152 /// <param name="m"></param> 153 /// <returns></returns> 154 private static string createzipfile(string path, int m) 155 { 156 try 157 { 158 Crc32 crc = new Crc32(); 159 using (FileStream fs = new FileStream(path, FileMode.Open)) 160 using (FileStream fszip = new FileStream(path + ".zip", FileMode.Create)) 161 { 162 ZipOutputStream zipout = new ZipOutputStream(fszip); 163 long pai = 1024 * 1024 * m; //每m兆写一次 164 long forint = fs.Length / pai + 1; 165 byte[] buffer; 166 var entry = new ZipEntry(Path.GetFileName(path)); 167 entry.Size = fs.Length; 168 entry.DateTime = DateTime.Now; 169 zipout.PutNextEntry(entry); 170 for (long i = 1; i <= forint; i++) 171 { 172 if (pai * i < fs.Length) 173 { 174 buffer = new byte[pai]; 175 fs.Seek(pai * (i - 1), SeekOrigin.Begin); 176 } 177 else 178 { 179 if (fs.Length < pai) 180 { 181 buffer = new byte[fs.Length]; 182 } 183 else 184 { 185 buffer = new byte[fs.Length - pai * (i - 1)]; 186 fs.Seek(pai * (i - 1), SeekOrigin.Begin); 187 } 188 } 189 fs.Read(buffer, 0, buffer.Length); 190 crc.Reset(); 191 crc.Update(buffer); 192 zipout.Write(buffer, 0, buffer.Length); 193 zipout.Flush(); 194 } 195 fs.Close(); 196 zipout.Finish(); 197 zipout.Close(); 198 //File.Delete(path); 199 return path + ".zip"; 200 } 201 } 202 catch (Exception ex) 203 { 204 string str = ex.Message; 205 return str; 206 } 207 } 208 */ 209 #endregion 210 211 212 #region 解压方法 213 /// <summary> 214 /// 把指定压缩包解压到指定文件夹,并返回解压文件数,文件夹为空时,解压到压缩包所在目录 215 /// </summary> 216 /// <param name="zipfilename"></param> 217 /// <param name="unzipDir"></param> 218 public static int UnZipFile(string zipfilename, string unzipDir = null) 219 { 220 int filecount = 0; 221 if (string.IsNullOrEmpty(unzipDir)) 222 { 223 unzipDir = Path.GetDirectoryName(zipfilename); 224 if (unzipDir == null) 225 throw new ArgumentException("目录信息不存在", "zipfilename"); 226 } 227 else if (!Directory.Exists(unzipDir)) 228 { 229 //生成解压目录 230 Directory.CreateDirectory(unzipDir); 231 } 232 using (ZipInputStream s = new ZipInputStream(File.OpenRead(zipfilename))) 233 { 234 ZipEntry theEntry; 235 while ((theEntry = s.GetNextEntry()) != null) 236 { 237 string path = Path.Combine(unzipDir, theEntry.Name); 238 if (theEntry.IsDirectory) 239 { 240 if (!Directory.Exists(path)) 241 Directory.CreateDirectory(path); 242 } 243 else if (theEntry.IsFile) 244 { 245 filecount++; 246 string dir = Path.GetDirectoryName(path); 247 if(string.IsNullOrEmpty(dir)) 248 throw new Exception("压缩文件有问题,有个文件没有目录" + path); 249 if (!Directory.Exists(dir)) 250 Directory.CreateDirectory(dir); 251 //解压文件到指定的目录) 252 using (FileStream fs = File.Create(path)) 253 { 254 byte[] data = new byte[2048]; 255 while (true) 256 { 257 int size = s.Read(data, 0, data.Length); 258 if (size <= 0) 259 break; 260 fs.Write(data, 0, size); 261 } 262 fs.Close(); 263 } 264 } 265 } 266 s.Close(); 267 } 268 return filecount; 269 } 270 #endregion 271 } 272 }
另外:还需添加bin 文件才能对代码编译成功:
SharpZipLib.dll
ICSharpCode.SharpZipLib.dll
直接在网上下载应该就能找到,至于网址我已经忘记了。
一点一滴 坚持,汇成知识的海洋~ 希望自己能进步!