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