CompressHelper.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446
  1. using System;
  2. using System.IO;
  3. using System.Text;
  4. using ICSharpCode.SharpZipLib.Checksum;
  5. using ICSharpCode.SharpZipLib.Zip;
  6. using SharpCompress.Archives;
  7. using SharpCompress.Archives.Zip;
  8. using SharpCompress.Common;
  9. using SharpCompress.Readers;
  10. using SharpCompress.Writers;
  11. namespace ShwasherSys
  12. {
  13. public static class CompressHelper
  14. {
  15. /// <summary>
  16. /// 解压
  17. /// </summary>
  18. /// <param name="sourcePath"></param>
  19. /// <param name="targetPath"></param>
  20. /// <returns></returns>
  21. public static bool UnCompress(this string sourcePath, string targetPath)
  22. {
  23. try
  24. {
  25. if (sourcePath.EndsWith(".zip"))
  26. {
  27. var archive = ArchiveFactory.Open(sourcePath);
  28. foreach (var entry in archive.Entries)
  29. {
  30. if (!entry.IsDirectory)
  31. {
  32. Console.WriteLine(entry.Key);
  33. entry.WriteToDirectory(targetPath, new ExtractionOptions() { ExtractFullPath = true, Overwrite = true });
  34. }
  35. }
  36. }
  37. else if (sourcePath.EndsWith(".rar"))
  38. {
  39. using (Stream stream = File.OpenRead(sourcePath))
  40. {
  41. var reader = ReaderFactory.Open(stream);
  42. while (reader.MoveToNextEntry())
  43. {
  44. if (!reader.Entry.IsDirectory)
  45. {
  46. reader.WriteEntryToDirectory(targetPath, new ExtractionOptions() { ExtractFullPath = true, Overwrite = true });
  47. }
  48. }
  49. }
  50. }
  51. return true;
  52. }
  53. catch (Exception e)
  54. {
  55. typeof(CompressHelper).LogError(e);
  56. }
  57. return false;
  58. }
  59. /// <summary>
  60. /// 压缩
  61. /// </summary>
  62. /// <param name="sourcePath"></param>
  63. /// <param name="targetPath"></param>
  64. /// <returns></returns>
  65. public static bool Compress(this string sourcePath, string targetPath)
  66. {
  67. try
  68. {
  69. using (var archive = ZipArchive.Create())
  70. {
  71. archive.AddAllFromDirectory(sourcePath);
  72. archive.SaveTo(targetPath, new WriterOptions(CompressionType.LZip));
  73. }
  74. return true;
  75. }
  76. catch (Exception e)
  77. {
  78. typeof(CompressHelper).LogError(e);
  79. }
  80. return false;
  81. }
  82. ///// <summary>
  83. ///// 单文件压缩(生成的压缩包和第三方的解压软件兼容)
  84. ///// </summary>
  85. ///// <param name="sourceFilePath"></param>
  86. ///// <returns></returns>
  87. //public static string CompressSingle( string sourceFilePath)
  88. //{
  89. // string zipFileName = sourceFilePath + ".gz";
  90. // using (FileStream sourceFileStream = new FileInfo(sourceFilePath).OpenRead())
  91. // {
  92. // using (FileStream zipFileStream = File.Create(zipFileName))
  93. // {
  94. // using (GZipStream zipStream = new GZipStream(zipFileStream, CompressionMode.Compress))
  95. // {
  96. // sourceFileStream.CopyTo(zipStream);
  97. // }
  98. // }
  99. // }
  100. // return zipFileName;
  101. //}
  102. ///// <summary>
  103. ///// 自定义多文件压缩(生成的压缩包和第三方的压缩文件解压不兼容)
  104. ///// </summary>
  105. ///// <param name="sourceFileList">文件列表</param>
  106. ///// <param name="saveFullPath">压缩包全路径</param>
  107. //public static void CompressMulti(this string[] sourceFileList, string saveFullPath)
  108. //{
  109. // MemoryStream ms = new MemoryStream();
  110. // foreach (string filePath in sourceFileList)
  111. // {
  112. // Console.WriteLine(filePath);
  113. // if (File.Exists(filePath))
  114. // {
  115. // string fileName = Path.GetFileName(filePath);
  116. // byte[] fileNameBytes = Encoding.UTF8.GetBytes(fileName ?? throw new InvalidOperationException());
  117. // byte[] sizeBytes = BitConverter.GetBytes(fileNameBytes.Length);
  118. // ms.Write(sizeBytes, 0, sizeBytes.Length);
  119. // ms.Write(fileNameBytes, 0, fileNameBytes.Length);
  120. // byte[] fileContentBytes = File.ReadAllBytes(filePath);
  121. // ms.Write(BitConverter.GetBytes(fileContentBytes.Length), 0, 4);
  122. // ms.Write(fileContentBytes, 0, fileContentBytes.Length);
  123. // }
  124. // }
  125. // ms.Flush();
  126. // ms.Position = 0;
  127. // using (FileStream zipFileStream = File.Create(saveFullPath))
  128. // {
  129. // using (GZipStream zipStream = new GZipStream(zipFileStream, CompressionMode.Compress))
  130. // {
  131. // ms.Position = 0;
  132. // ms.CopyTo(zipStream);
  133. // }
  134. // }
  135. // ms.Close();
  136. //}
  137. ///// <summary>
  138. ///// 多文件压缩解压
  139. ///// </summary>
  140. ///// <param name="zipPath">压缩文件路径</param>
  141. ///// <param name="targetPath">解压目录</param>
  142. ///// <param name="fileName"></param>
  143. //public static void DeCompressMulti(this string zipPath, string targetPath,string fileName=null)
  144. //{
  145. // byte[] fileSize = new byte[4];
  146. // if (File.Exists(zipPath))
  147. // {
  148. // using (FileStream fStream = File.Open(zipPath, FileMode.Open))
  149. // {
  150. // using (MemoryStream ms = new MemoryStream())
  151. // {
  152. // using (GZipStream zipStream = new GZipStream(fStream, CompressionMode.Decompress))
  153. // {
  154. // zipStream.CopyTo(ms);
  155. // }
  156. // ms.Position = 0;
  157. // while (ms.Position != ms.Length)
  158. // {
  159. // ms.Read(fileSize, 0, fileSize.Length);
  160. // int fileNameLength = BitConverter.ToInt32(fileSize, 0);
  161. // byte[] fileNameBytes = new byte[fileNameLength];
  162. // ms.Read(fileNameBytes, 0, fileNameBytes.Length);
  163. // fileName = fileName ?? Encoding.UTF8.GetString(fileNameBytes);
  164. // string fileFulleName = targetPath + fileName;
  165. // ms.Read(fileSize, 0, 4);
  166. // int fileContentLength = BitConverter.ToInt32(fileSize, 0);
  167. // byte[] fileContentBytes = new byte[fileContentLength];
  168. // ms.Read(fileContentBytes, 0, fileContentBytes.Length);
  169. // using (FileStream childFileStream = File.Create(fileFulleName))
  170. // {
  171. // childFileStream.Write(fileContentBytes, 0, fileContentBytes.Length);
  172. // }
  173. // }
  174. // }
  175. // }
  176. // }
  177. //}
  178. }
  179. /// <summary>
  180. /// 只适用于ZIP压缩
  181. /// </summary>
  182. public static class ZipHelper
  183. {
  184. #region 压缩
  185. /// <summary>
  186. /// 压缩文件或文件夹
  187. /// </summary>
  188. /// <param name="fileToZip">要压缩的路径</param>
  189. /// <param name="zipedFile">压缩后的文件名</param>
  190. /// <param name="password">密码</param>
  191. /// <returns>压缩结果</returns>
  192. public static bool Zip(string fileToZip, string zipedFile, string password = null)
  193. {
  194. bool result = false;
  195. if (Directory.Exists(fileToZip))
  196. result = ZipDirectory(fileToZip, zipedFile, password);
  197. else if (File.Exists(fileToZip))
  198. result = ZipFile(fileToZip, zipedFile, password);
  199. return result;
  200. }
  201. /// <summary>
  202. /// 压缩文件夹
  203. /// </summary>
  204. /// <param name="folderToZip">要压缩的文件夹路径</param>
  205. /// <param name="zipedFile">压缩文件完整路径</param>
  206. /// <param name="password">密码</param>
  207. /// <returns>是否压缩成功</returns>
  208. public static bool ZipDirectory(string folderToZip, string zipedFile, string password = null)
  209. {
  210. if (!Directory.Exists(folderToZip))
  211. return false;
  212. ZipOutputStream zipStream = new ZipOutputStream(File.Create(zipedFile));
  213. zipStream.SetLevel(6);
  214. if (!string.IsNullOrEmpty(password)) zipStream.Password = password;
  215. var result = ZipDirectory(folderToZip, zipStream, "");
  216. zipStream.Finish();
  217. zipStream.Close();
  218. return result;
  219. }
  220. /// <summary>
  221. /// 压缩文件
  222. /// </summary>
  223. /// <param name="fileToZip">要压缩的文件全名</param>
  224. /// <param name="zipedFile">压缩后的文件名</param>
  225. /// <param name="password">密码</param>
  226. /// <returns>压缩结果</returns>
  227. public static bool ZipFile(string fileToZip, string zipedFile, string password = null)
  228. {
  229. bool result = true;
  230. ZipOutputStream zipStream = null;
  231. FileStream fs = null;
  232. if (!File.Exists(fileToZip))
  233. return false;
  234. try
  235. {
  236. fs = File.OpenRead(fileToZip);
  237. byte[] buffer = new byte[fs.Length];
  238. fs.Read(buffer, 0, buffer.Length);
  239. fs.Close();
  240. fs = File.Create(zipedFile);
  241. zipStream = new ZipOutputStream(fs);
  242. if (!string.IsNullOrEmpty(password)) zipStream.Password = password;
  243. var ent = new ZipEntry(Path.GetFileName(fileToZip));
  244. zipStream.PutNextEntry(ent);
  245. zipStream.SetLevel(6);
  246. zipStream.Write(buffer, 0, buffer.Length);
  247. }
  248. catch
  249. {
  250. result = false;
  251. }
  252. finally
  253. {
  254. if (zipStream != null)
  255. {
  256. zipStream.Finish();
  257. zipStream.Close();
  258. }
  259. if (fs != null)
  260. {
  261. fs.Close();
  262. fs.Dispose();
  263. }
  264. }
  265. GC.Collect();
  266. GC.Collect(1);
  267. return result;
  268. }
  269. /// <summary>
  270. /// 递归压缩文件夹的内部方法
  271. /// </summary>
  272. /// <param name="folderToZip">要压缩的文件夹路径</param>
  273. /// <param name="zipStream">压缩输出流</param>
  274. /// <param name="parentFolderName">此文件夹的上级文件夹</param>
  275. /// <returns></returns>
  276. private static bool ZipDirectory(string folderToZip, ZipOutputStream zipStream, string parentFolderName)
  277. {
  278. bool result = true;
  279. FileStream fs = null;
  280. Crc32 crc = new Crc32();
  281. try
  282. {
  283. var ent = new ZipEntry(Path.Combine(parentFolderName, Path.GetFileName(folderToZip) + "/"));
  284. zipStream.PutNextEntry(ent);
  285. zipStream.Flush();
  286. var files = Directory.GetFiles(folderToZip);
  287. foreach (string file in files)
  288. {
  289. fs = File.OpenRead(file);
  290. byte[] buffer = new byte[fs.Length];
  291. fs.Read(buffer, 0, buffer.Length);
  292. ent = new ZipEntry(Path.Combine(parentFolderName,
  293. Path.GetFileName(folderToZip) + "/" + Path.GetFileName(file)))
  294. {
  295. DateTime = DateTime.Now,
  296. Size = fs.Length
  297. };
  298. fs.Close();
  299. crc.Reset();
  300. crc.Update(buffer);
  301. ent.Crc = crc.Value;
  302. zipStream.PutNextEntry(ent);
  303. zipStream.Write(buffer, 0, buffer.Length);
  304. }
  305. }
  306. catch
  307. {
  308. result = false;
  309. }
  310. finally
  311. {
  312. if (fs != null)
  313. {
  314. fs.Close();
  315. fs.Dispose();
  316. }
  317. GC.Collect();
  318. GC.Collect(1);
  319. }
  320. var folders = Directory.GetDirectories(folderToZip);
  321. foreach (string folder in folders)
  322. if (!ZipDirectory(folder, zipStream, folderToZip))
  323. return false;
  324. return result;
  325. }
  326. #endregion
  327. #region 解压
  328. /// <summary>
  329. /// 解压功能(解压压缩文件到指定目录)
  330. /// </summary>
  331. /// <param name="fileToUnZip">待解压的文件</param>
  332. /// <param name="zipedFolder">指定解压目标目录</param>
  333. /// <param name="password">密码</param>
  334. /// <returns>解压结果</returns>
  335. public static bool UnZip(this string fileToUnZip, string zipedFolder, string password = null)
  336. {
  337. bool result = true;
  338. FileStream fs = null;
  339. ZipInputStream zipStream = null;
  340. if (!File.Exists(fileToUnZip))
  341. return false;
  342. if (!Directory.Exists(zipedFolder))
  343. Directory.CreateDirectory(zipedFolder);
  344. try
  345. {
  346. zipStream = new ZipInputStream(File.OpenRead(fileToUnZip));
  347. if (!string.IsNullOrEmpty(password))
  348. zipStream.Password = password;
  349. ZipEntry ent;
  350. while ((ent = zipStream.GetNextEntry()) != null)
  351. {
  352. if (!string.IsNullOrEmpty(ent.Name))
  353. {
  354. var fileName = Path.Combine(zipedFolder, ent.Name);
  355. fileName = fileName.Replace('/', '\\');//change by Mr.HopeGi
  356. if (fileName.EndsWith("\\"))
  357. {
  358. Directory.CreateDirectory(fileName);
  359. continue;
  360. }
  361. fs = File.Create(fileName);
  362. int size = 2048;
  363. byte[] data = new byte[size];
  364. while (true)
  365. {
  366. size = zipStream.Read(data, 0, data.Length);
  367. if (size > 0)
  368. fs.Write(data, 0, data.Length);
  369. else
  370. break;
  371. }
  372. }
  373. }
  374. }
  375. catch (Exception e)
  376. {
  377. typeof(ZipHelper).LogError(e);
  378. result = false;
  379. }
  380. finally
  381. {
  382. if (fs != null)
  383. {
  384. fs.Close();
  385. fs.Dispose();
  386. }
  387. if (zipStream != null)
  388. {
  389. zipStream.Close();
  390. zipStream.Dispose();
  391. }
  392. GC.Collect();
  393. GC.Collect(1);
  394. }
  395. return result;
  396. }
  397. #endregion
  398. }
  399. }