星火微课系统客户端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

CLeopardZip.cs 24KB

4 vuotta sitten
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637
  1. using ICSharpCode.SharpZipLib.Checksums;
  2. using ICSharpCode.SharpZipLib.Zip;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.IO;
  6. namespace Common.system
  7. {
  8. /// <summary>
  9. /// 适用与ZIP压缩
  10. /// </summary>
  11. public class ZipHelper
  12. {
  13. #region 压缩
  14. /// <summary>
  15. /// 递归压缩文件夹的内部方法
  16. /// </summary>
  17. /// <param name="folderToZip">要压缩的文件夹路径</param>
  18. /// <param name="zipStream">压缩输出流</param>
  19. /// <param name="parentFolderName">此文件夹的上级文件夹</param>
  20. /// <returns></returns>
  21. private static bool ZipDirectory(string folderToZip, ZipOutputStream zipStream, string parentFolderName)
  22. {
  23. bool result = true;
  24. string[] folders, files;
  25. ZipEntry ent = null;
  26. FileStream fs = null;
  27. Crc32 crc = new Crc32();
  28. try
  29. {
  30. ent = new ZipEntry(Path.Combine(parentFolderName, Path.GetFileName(folderToZip) + "/"));
  31. zipStream.PutNextEntry(ent);
  32. zipStream.Flush();
  33. files = Directory.GetFiles(folderToZip);
  34. foreach (string file in files)
  35. {
  36. fs = File.OpenRead(file);
  37. byte[] buffer = new byte[fs.Length];
  38. fs.Read(buffer, 0, buffer.Length);
  39. ent = new ZipEntry(Path.Combine(parentFolderName, Path.GetFileName(folderToZip) + "/" + Path.GetFileName(file)));
  40. ent.DateTime = DateTime.Now;
  41. ent.Size = fs.Length;
  42. fs.Close();
  43. crc.Reset();
  44. crc.Update(buffer);
  45. ent.Crc = crc.Value;
  46. zipStream.PutNextEntry(ent);
  47. zipStream.Write(buffer, 0, buffer.Length);
  48. }
  49. }
  50. catch
  51. {
  52. result = false;
  53. }
  54. finally
  55. {
  56. if (fs != null)
  57. {
  58. fs.Close();
  59. fs.Dispose();
  60. }
  61. if (ent != null)
  62. {
  63. ent = null;
  64. }
  65. GC.Collect();
  66. GC.Collect(1);
  67. }
  68. folders = Directory.GetDirectories(folderToZip);
  69. foreach (string folder in folders)
  70. if (!ZipDirectory(folder, zipStream, folderToZip))
  71. return false;
  72. return result;
  73. }
  74. /// <summary>
  75. /// 压缩文件夹
  76. /// </summary>
  77. /// <param name="folderToZip">要压缩的文件夹路径</param>
  78. /// <param name="zipedFile">压缩文件完整路径</param>
  79. /// <param name="password">密码</param>
  80. /// <returns>是否压缩成功</returns>
  81. public static bool ZipDirectory(string folderToZip, string zipedFile, string password)
  82. {
  83. bool result = false;
  84. if (!Directory.Exists(folderToZip))
  85. return result;
  86. ZipOutputStream zipStream = new ZipOutputStream(File.Create(zipedFile));
  87. zipStream.SetLevel(6);
  88. if (!string.IsNullOrEmpty(password)) zipStream.Password = password;
  89. result = ZipDirectory(folderToZip, zipStream, "");
  90. zipStream.Finish();
  91. zipStream.Close();
  92. return result;
  93. }
  94. /// <summary>
  95. /// 压缩文件夹
  96. /// </summary>
  97. /// <param name="folderToZip">要压缩的文件夹路径</param>
  98. /// <param name="zipedFile">压缩文件完整路径</param>
  99. /// <returns>是否压缩成功</returns>
  100. public static bool ZipDirectory(string folderToZip, string zipedFile)
  101. {
  102. bool result = ZipDirectory(folderToZip, zipedFile, null);
  103. return result;
  104. }
  105. /// <summary>
  106. /// 压缩文件
  107. /// </summary>
  108. /// <param name="fileToZip">要压缩的文件全名</param>
  109. /// <param name="zipedFile">压缩后的文件名</param>
  110. /// <param name="password">密码</param>
  111. /// <returns>压缩结果</returns>
  112. public static bool ZipFile(string fileToZip, string zipedFile, string password)
  113. {
  114. bool result = true;
  115. ZipOutputStream zipStream = null;
  116. FileStream fs = null;
  117. ZipEntry ent = null;
  118. if (!File.Exists(fileToZip))
  119. return false;
  120. try
  121. {
  122. fs = File.OpenRead(fileToZip);
  123. byte[] buffer = new byte[fs.Length];
  124. fs.Read(buffer, 0, buffer.Length);
  125. fs.Close();
  126. fs = File.Create(zipedFile);
  127. zipStream = new ZipOutputStream(fs);
  128. if (!string.IsNullOrEmpty(password)) zipStream.Password = password;
  129. ent = new ZipEntry(Path.GetFileName(fileToZip));
  130. zipStream.PutNextEntry(ent);
  131. zipStream.SetLevel(6);
  132. zipStream.Write(buffer, 0, buffer.Length);
  133. }
  134. catch
  135. {
  136. result = false;
  137. }
  138. finally
  139. {
  140. if (zipStream != null)
  141. {
  142. zipStream.Finish();
  143. zipStream.Close();
  144. }
  145. if (ent != null)
  146. {
  147. ent = null;
  148. }
  149. if (fs != null)
  150. {
  151. fs.Close();
  152. fs.Dispose();
  153. }
  154. }
  155. GC.Collect();
  156. GC.Collect(1);
  157. return result;
  158. }
  159. /// <summary>
  160. /// 压缩文件
  161. /// </summary>
  162. /// <param name="fileToZip">要压缩的文件全名</param>
  163. /// <param name="zipedFile">压缩后的文件名</param>
  164. /// <returns>压缩结果</returns>
  165. public static bool ZipFile(string fileToZip, string zipedFile)
  166. {
  167. bool result = ZipFile(fileToZip, zipedFile, null);
  168. return result;
  169. }
  170. /// <summary>
  171. /// 压缩文件或文件夹
  172. /// </summary>
  173. /// <param name="fileToZip">要压缩的路径</param>
  174. /// <param name="zipedFile">压缩后的文件名</param>
  175. /// <param name="password">密码</param>
  176. /// <returns>压缩结果</returns>
  177. public static bool Zip(string fileToZip, string zipedFile, string password)
  178. {
  179. bool result = false;
  180. if (Directory.Exists(fileToZip))
  181. result = ZipDirectory(fileToZip, zipedFile, password);
  182. else if (File.Exists(fileToZip))
  183. result = ZipFile(fileToZip, zipedFile, password);
  184. return result;
  185. }
  186. /// <summary>
  187. /// 压缩文件或文件夹
  188. /// </summary>
  189. /// <param name="fileToZip">要压缩的路径</param>
  190. /// <param name="zipedFile">压缩后的文件名</param>
  191. /// <returns>压缩结果</returns>
  192. public static bool Zip(string fileToZip, string zipedFile)
  193. {
  194. bool result = Zip(fileToZip, zipedFile, null);
  195. return result;
  196. }
  197. #endregion
  198. #region 解压
  199. /// <summary>
  200. /// 解压功能(解压压缩文件到指定目录)
  201. /// </summary>
  202. /// <param name="fileToUnZip">待解压的文件</param>
  203. /// <param name="zipedFolder">指定解压目标目录</param>
  204. /// <param name="password">密码</param>
  205. /// <returns>解压结果</returns>
  206. public static bool UnZip(string fileToUnZip, string zipedFolder, string password)
  207. {
  208. bool result = true;
  209. FileStream fs = null;
  210. ZipInputStream zipStream = null;
  211. ZipEntry ent = null;
  212. string fileName;
  213. if (!File.Exists(fileToUnZip))
  214. return false;
  215. if (!Directory.Exists(zipedFolder))
  216. Directory.CreateDirectory(zipedFolder);
  217. try
  218. {
  219. zipStream = new ZipInputStream(File.OpenRead(fileToUnZip));
  220. if (!string.IsNullOrEmpty(password)) zipStream.Password = password;
  221. while ((ent = zipStream.GetNextEntry()) != null)
  222. {
  223. if (!string.IsNullOrEmpty(ent.Name))
  224. {
  225. fileName = Path.Combine(zipedFolder, ent.Name);
  226. fileName = fileName.Replace('/', '\\');//change by Mr.HopeGi
  227. if (fileName.EndsWith("\\"))
  228. {
  229. Directory.CreateDirectory(fileName);
  230. continue;
  231. }
  232. fs = File.Create(fileName);
  233. int size = 2048;
  234. byte[] data = new byte[size];
  235. while (true)
  236. {
  237. size = zipStream.Read(data, 0, data.Length);
  238. if (size > 0)
  239. fs.Write(data, 0, data.Length);
  240. else
  241. break;
  242. }
  243. }
  244. }
  245. }
  246. catch
  247. {
  248. result = false;
  249. }
  250. finally
  251. {
  252. if (fs != null)
  253. {
  254. fs.Close();
  255. fs.Dispose();
  256. }
  257. if (zipStream != null)
  258. {
  259. zipStream.Close();
  260. zipStream.Dispose();
  261. }
  262. if (ent != null)
  263. {
  264. ent = null;
  265. }
  266. GC.Collect();
  267. GC.Collect(1);
  268. }
  269. return result;
  270. }
  271. /// <summary>
  272. /// 解压功能(解压压缩文件到指定目录)
  273. /// </summary>
  274. /// <param name="fileToUnZip">待解压的文件</param>
  275. /// <param name="zipedFolder">指定解压目标目录</param>
  276. /// <returns>解压结果</returns>
  277. public static bool UnZip(string fileToUnZip, string zipedFolder)
  278. {
  279. bool result = NewUnZip(fileToUnZip, zipedFolder, null, true);
  280. return result;
  281. }
  282. /// <summary>
  283. /// ZIP:解压一个zip文件
  284. /// </summary>
  285. /// <param name="ZipFile">需要解压的Zip文件(绝对路径)</param>
  286. /// <param name="TargetDirectory">解压到的目录</param>
  287. /// <param name="Password">解压密码</param>
  288. /// <param name="OverWrite">是否覆盖已存在的文件</param>
  289. public static bool NewUnZip(string ZipFile, string TargetDirectory, string Password, bool OverWrite = true)
  290. {
  291. try
  292. {
  293. //如果解压到的目录不存在,则报错
  294. if (!System.IO.Directory.Exists(TargetDirectory))
  295. {
  296. throw new System.IO.FileNotFoundException("指定的目录: " + TargetDirectory + " 不存在!");
  297. }
  298. //目录结尾
  299. if (!TargetDirectory.EndsWith("\\")) { TargetDirectory = TargetDirectory + "\\"; }
  300. using (ZipInputStream zipfiles = new ZipInputStream(File.OpenRead(ZipFile)))
  301. {
  302. zipfiles.Password = Password;
  303. ZipEntry theEntry;
  304. while ((theEntry = zipfiles.GetNextEntry()) != null)
  305. {
  306. string directoryName = "";
  307. string pathToZip = "";
  308. pathToZip = theEntry.Name;
  309. if (pathToZip != "")
  310. directoryName = Path.GetDirectoryName(pathToZip) + "\\";
  311. string fileName = Path.GetFileName(pathToZip);
  312. Directory.CreateDirectory(TargetDirectory + directoryName);
  313. if (fileName != "")
  314. {
  315. if ((File.Exists(TargetDirectory + directoryName + fileName) && OverWrite) || (!File.Exists(TargetDirectory + directoryName + fileName)))
  316. {
  317. try
  318. {
  319. using (FileStream streamWriter = File.Create(TargetDirectory + directoryName + fileName))
  320. {
  321. int size = 2048;
  322. byte[] data = new byte[2048];
  323. while (true)
  324. {
  325. size = zipfiles.Read(data, 0, data.Length);
  326. if (size > 0)
  327. streamWriter.Write(data, 0, size);
  328. else
  329. break;
  330. }
  331. streamWriter.Close();
  332. }
  333. }
  334. catch (Exception ex)
  335. {
  336. string message = ex.Message;
  337. //解压出错//若文件无损坏则可能为无法覆盖文件
  338. }
  339. }
  340. }
  341. }
  342. zipfiles.Close();
  343. }
  344. return true;
  345. }
  346. catch (Exception)
  347. {
  348. return false;
  349. }
  350. }
  351. #endregion
  352. #region 压缩文件
  353. /// <summary>
  354. /// 压缩文件
  355. /// </summary>
  356. /// <param name="fileNames">要打包的文件列表</param>
  357. /// <param name="GzipFileName">目标文件名</param>
  358. /// <param name="CompressionLevel">压缩品质级别(0~9)</param>
  359. /// <param name="deleteFile">是否删除原文件</param>
  360. public static void CompressFile(List<FileInfo> fileNames, string GzipFileName, int CompressionLevel, bool deleteFile)
  361. {
  362. ZipOutputStream s = new ZipOutputStream(File.Create(GzipFileName));
  363. try
  364. {
  365. s.SetLevel(CompressionLevel); //0 - store only to 9 - means best compression
  366. foreach (FileInfo file in fileNames)
  367. {
  368. FileStream fs = null;
  369. try
  370. {
  371. fs = file.Open(FileMode.Open, FileAccess.ReadWrite);
  372. }
  373. catch
  374. { continue; }
  375. // 方法二,将文件分批读入缓冲区
  376. byte[] data = new byte[2048];
  377. int size = 2048;
  378. ZipEntry entry = new ZipEntry(Path.GetFileName(file.Name));
  379. entry.DateTime = (file.CreationTime > file.LastWriteTime ? file.LastWriteTime : file.CreationTime);
  380. s.PutNextEntry(entry);
  381. while (true)
  382. {
  383. size = fs.Read(data, 0, size);
  384. if (size <= 0) break;
  385. s.Write(data, 0, size);
  386. }
  387. fs.Close();
  388. if (deleteFile)
  389. {
  390. file.Delete();
  391. }
  392. }
  393. }
  394. finally
  395. {
  396. s.Finish();
  397. s.Close();
  398. }
  399. }
  400. public static void CompressFile(string fileName, string GzipFileName, int CompressionLevel, bool deleteFile)
  401. {
  402. ZipOutputStream s = new ZipOutputStream(File.Create(GzipFileName));
  403. try
  404. {
  405. s.SetLevel(CompressionLevel); //0 - store only to 9 - means best compression
  406. FileInfo file = new FileInfo(fileName);
  407. FileStream fs = null;
  408. try
  409. {
  410. fs = file.Open(FileMode.Open, FileAccess.ReadWrite);
  411. }
  412. catch
  413. { return; }
  414. // 方法二,将文件分批读入缓冲区
  415. byte[] data = new byte[2048];
  416. int size = 2048;
  417. ZipEntry entry = new ZipEntry(Path.GetFileName(file.Name));
  418. entry.DateTime = (file.CreationTime > file.LastWriteTime ? file.LastWriteTime : file.CreationTime);
  419. s.PutNextEntry(entry);
  420. while (true)
  421. {
  422. size = fs.Read(data, 0, size);
  423. if (size <= 0) break;
  424. s.Write(data, 0, size);
  425. }
  426. fs.Close();
  427. if (deleteFile)
  428. {
  429. file.Delete();
  430. }
  431. }
  432. finally
  433. {
  434. s.Finish();
  435. s.Close();
  436. }
  437. }
  438. /// <summary>
  439. /// 压缩文件夹
  440. /// </summary>
  441. /// <param name="dirPath">要打包的文件夹</param>
  442. /// <param name="GzipFileName">目标文件名</param>
  443. /// <param name="CompressionLevel">压缩品质级别(0~9)</param>
  444. /// <param name="deleteDir">是否删除原文件夹</param>
  445. public static void CompressDirectory(string dirPath, string GzipFileName, int CompressionLevel, bool deleteDir)
  446. {
  447. //压缩文件为空时默认与压缩文件夹同一级目录
  448. if (GzipFileName == string.Empty)
  449. {
  450. GzipFileName = dirPath.Substring(dirPath.LastIndexOf("//") + 1);
  451. GzipFileName = dirPath.Substring(0, dirPath.LastIndexOf("//")) + "//" + GzipFileName + ".zip";
  452. }
  453. //if (Path.GetExtension(GzipFileName) != ".zip")
  454. //{
  455. // GzipFileName = GzipFileName + ".zip";
  456. //}
  457. using (ZipOutputStream zipoutputstream = new ZipOutputStream(File.Create(GzipFileName)))
  458. {
  459. zipoutputstream.SetLevel(CompressionLevel);
  460. Crc32 crc = new Crc32();
  461. Dictionary<string, DateTime> fileList = GetAllFies(dirPath);
  462. foreach (KeyValuePair<string, DateTime> item in fileList)
  463. {
  464. FileStream fs = File.OpenRead(item.Key.ToString());
  465. byte[] buffer = new byte[fs.Length];
  466. fs.Read(buffer, 0, buffer.Length);
  467. ZipEntry entry = new ZipEntry(item.Key.Substring(dirPath.Length));
  468. entry.DateTime = item.Value;
  469. entry.Size = fs.Length;
  470. fs.Close();
  471. crc.Reset();
  472. crc.Update(buffer);
  473. entry.Crc = crc.Value;
  474. zipoutputstream.PutNextEntry(entry);
  475. zipoutputstream.Write(buffer, 0, buffer.Length);
  476. }
  477. }
  478. if (deleteDir)
  479. {
  480. Directory.Delete(dirPath, true);
  481. }
  482. }
  483. /// <summary>
  484. /// 获取所有文件
  485. /// </summary>
  486. /// <returns></returns>
  487. private static Dictionary<string, DateTime> GetAllFies(string dir)
  488. {
  489. Dictionary<string, DateTime> FilesList = new Dictionary<string, DateTime>();
  490. DirectoryInfo fileDire = new DirectoryInfo(dir);
  491. if (!fileDire.Exists)
  492. {
  493. throw new System.IO.FileNotFoundException("目录:" + fileDire.FullName + "没有找到!");
  494. }
  495. GetAllDirFiles(fileDire, FilesList);
  496. GetAllDirsFiles(fileDire.GetDirectories(), FilesList);
  497. return FilesList;
  498. }
  499. /// <summary>
  500. /// 获取一个文件夹下的所有文件夹里的文件
  501. /// </summary>
  502. /// <param name="dirs"></param>
  503. /// <param name="filesList"></param>
  504. private static void GetAllDirsFiles(DirectoryInfo[] dirs, Dictionary<string, DateTime> filesList)
  505. {
  506. foreach (DirectoryInfo dir in dirs)
  507. {
  508. foreach (FileInfo file in dir.GetFiles("*.*"))
  509. {
  510. filesList.Add(file.FullName, file.LastWriteTime);
  511. }
  512. GetAllDirsFiles(dir.GetDirectories(), filesList);
  513. }
  514. }
  515. /// <summary>
  516. /// 获取一个文件夹下的文件
  517. /// </summary>
  518. /// <param name="dir">目录名称</param>
  519. /// <param name="filesList">文件列表HastTable</param>
  520. private static void GetAllDirFiles(DirectoryInfo dir, Dictionary<string, DateTime> filesList)
  521. {
  522. foreach (FileInfo file in dir.GetFiles("*.*"))
  523. {
  524. filesList.Add(file.FullName, file.LastWriteTime);
  525. }
  526. }
  527. #endregion
  528. #region 解压缩文件
  529. /// <summary>
  530. /// 解压缩文件
  531. /// </summary>
  532. /// <param name="GzipFile">压缩包文件名</param>
  533. /// <param name="targetPath">解压缩目标路径</param>
  534. public static void Decompress(string GzipFile, string targetPath)
  535. {
  536. //string directoryName = Path.GetDirectoryName(targetPath + "//") + "//";
  537. string directoryName = targetPath;
  538. if (!Directory.Exists(directoryName)) Directory.CreateDirectory(directoryName);//生成解压目录
  539. string CurrentDirectory = directoryName;
  540. byte[] data = new byte[2048];
  541. int size = 2048;
  542. ZipEntry theEntry = null;
  543. using (ZipInputStream s = new ZipInputStream(File.OpenRead(GzipFile)))
  544. {
  545. while ((theEntry = s.GetNextEntry()) != null)
  546. {
  547. if (theEntry.IsDirectory)
  548. {// 该结点是目录
  549. if (!Directory.Exists(CurrentDirectory + theEntry.Name)) Directory.CreateDirectory(CurrentDirectory + theEntry.Name);
  550. }
  551. else
  552. {
  553. if (theEntry.Name != String.Empty)
  554. {
  555. // 检查多级目录是否存在
  556. if (theEntry.Name.Contains("\\"))
  557. {
  558. string parentDirPath = theEntry.Name.Remove(theEntry.Name.LastIndexOf("\\") + 1);
  559. if (!Directory.Exists(parentDirPath))
  560. {
  561. Directory.CreateDirectory(CurrentDirectory + parentDirPath);
  562. }
  563. }
  564. //解压文件到指定的目录
  565. using (FileStream streamWriter = File.Create(CurrentDirectory + theEntry.Name))
  566. {
  567. while (true)
  568. {
  569. size = s.Read(data, 0, data.Length);
  570. if (size <= 0) break;
  571. streamWriter.Write(data, 0, size);
  572. }
  573. streamWriter.Close();
  574. }
  575. }
  576. }
  577. }
  578. s.Close();
  579. }
  580. }
  581. #endregion
  582. }
  583. }