|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.IO;
- using ICSharpCode.SharpZipLib;
- using ICSharpCode.SharpZipLib.Zip;
- using ICSharpCode.SharpZipLib.Checksums;
-
- namespace Common.system
- {
- /// <summary>
- /// 适用与ZIP压缩
- /// </summary>
- public class ZipHelper
- {
- #region 压缩
-
- /// <summary>
- /// 递归压缩文件夹的内部方法
- /// </summary>
- /// <param name="folderToZip">要压缩的文件夹路径</param>
- /// <param name="zipStream">压缩输出流</param>
- /// <param name="parentFolderName">此文件夹的上级文件夹</param>
- /// <returns></returns>
- private static bool ZipDirectory(string folderToZip, ZipOutputStream zipStream, string parentFolderName)
- {
- bool result = true;
- string[] folders, files;
- ZipEntry ent = null;
- FileStream fs = null;
- Crc32 crc = new Crc32();
-
- try
- {
- ent = new ZipEntry(Path.Combine(parentFolderName, Path.GetFileName(folderToZip) + "/"));
- zipStream.PutNextEntry(ent);
- zipStream.Flush();
-
- files = Directory.GetFiles(folderToZip);
- foreach (string file in files)
- {
- fs = File.OpenRead(file);
-
- byte[] buffer = new byte[fs.Length];
- fs.Read(buffer, 0, buffer.Length);
- ent = new ZipEntry(Path.Combine(parentFolderName, Path.GetFileName(folderToZip) + "/" + Path.GetFileName(file)));
- ent.DateTime = DateTime.Now;
- ent.Size = fs.Length;
-
- fs.Close();
-
- crc.Reset();
- crc.Update(buffer);
-
- ent.Crc = crc.Value;
- zipStream.PutNextEntry(ent);
- zipStream.Write(buffer, 0, buffer.Length);
- }
-
- }
- catch
- {
- result = false;
- }
- finally
- {
- if (fs != null)
- {
- fs.Close();
- fs.Dispose();
- }
- if (ent != null)
- {
- ent = null;
- }
- GC.Collect();
- GC.Collect(1);
- }
-
- folders = Directory.GetDirectories(folderToZip);
- foreach (string folder in folders)
- if (!ZipDirectory(folder, zipStream, folderToZip))
- return false;
-
- return result;
- }
-
- /// <summary>
- /// 压缩文件夹
- /// </summary>
- /// <param name="folderToZip">要压缩的文件夹路径</param>
- /// <param name="zipedFile">压缩文件完整路径</param>
- /// <param name="password">密码</param>
- /// <returns>是否压缩成功</returns>
- public static bool ZipDirectory(string folderToZip, string zipedFile, string password)
- {
- bool result = false;
- if (!Directory.Exists(folderToZip))
- return result;
-
- ZipOutputStream zipStream = new ZipOutputStream(File.Create(zipedFile));
- zipStream.SetLevel(6);
- if (!string.IsNullOrEmpty(password)) zipStream.Password = password;
-
- result = ZipDirectory(folderToZip, zipStream, "");
-
- zipStream.Finish();
- zipStream.Close();
-
- return result;
- }
-
- /// <summary>
- /// 压缩文件夹
- /// </summary>
- /// <param name="folderToZip">要压缩的文件夹路径</param>
- /// <param name="zipedFile">压缩文件完整路径</param>
- /// <returns>是否压缩成功</returns>
- public static bool ZipDirectory(string folderToZip, string zipedFile)
- {
- bool result = ZipDirectory(folderToZip, zipedFile, null);
- return result;
- }
-
- /// <summary>
- /// 压缩文件
- /// </summary>
- /// <param name="fileToZip">要压缩的文件全名</param>
- /// <param name="zipedFile">压缩后的文件名</param>
- /// <param name="password">密码</param>
- /// <returns>压缩结果</returns>
- public static bool ZipFile(string fileToZip, string zipedFile, string password)
- {
- bool result = true;
- ZipOutputStream zipStream = null;
- FileStream fs = null;
- ZipEntry ent = null;
-
- if (!File.Exists(fileToZip))
- return false;
-
- try
- {
- fs = File.OpenRead(fileToZip);
- byte[] buffer = new byte[fs.Length];
- fs.Read(buffer, 0, buffer.Length);
- fs.Close();
-
- fs = File.Create(zipedFile);
- zipStream = new ZipOutputStream(fs);
- if (!string.IsNullOrEmpty(password)) zipStream.Password = password;
- ent = new ZipEntry(Path.GetFileName(fileToZip));
- zipStream.PutNextEntry(ent);
- zipStream.SetLevel(6);
-
- zipStream.Write(buffer, 0, buffer.Length);
-
- }
- catch
- {
- result = false;
- }
- finally
- {
- if (zipStream != null)
- {
- zipStream.Finish();
- zipStream.Close();
- }
- if (ent != null)
- {
- ent = null;
- }
- if (fs != null)
- {
- fs.Close();
- fs.Dispose();
- }
- }
- GC.Collect();
- GC.Collect(1);
-
- return result;
- }
-
- /// <summary>
- /// 压缩文件
- /// </summary>
- /// <param name="fileToZip">要压缩的文件全名</param>
- /// <param name="zipedFile">压缩后的文件名</param>
- /// <returns>压缩结果</returns>
- public static bool ZipFile(string fileToZip, string zipedFile)
- {
- bool result = ZipFile(fileToZip, zipedFile, null);
- return result;
- }
-
- /// <summary>
- /// 压缩文件或文件夹
- /// </summary>
- /// <param name="fileToZip">要压缩的路径</param>
- /// <param name="zipedFile">压缩后的文件名</param>
- /// <param name="password">密码</param>
- /// <returns>压缩结果</returns>
- public static bool Zip(string fileToZip, string zipedFile, string password)
- {
- bool result = false;
- if (Directory.Exists(fileToZip))
- result = ZipDirectory(fileToZip, zipedFile, password);
- else if (File.Exists(fileToZip))
- result = ZipFile(fileToZip, zipedFile, password);
-
- return result;
- }
-
- /// <summary>
- /// 压缩文件或文件夹
- /// </summary>
- /// <param name="fileToZip">要压缩的路径</param>
- /// <param name="zipedFile">压缩后的文件名</param>
- /// <returns>压缩结果</returns>
- public static bool Zip(string fileToZip, string zipedFile)
- {
- bool result = Zip(fileToZip, zipedFile, null);
- return result;
-
- }
-
- #endregion
-
- #region 解压
-
- /// <summary>
- /// 解压功能(解压压缩文件到指定目录)
- /// </summary>
- /// <param name="fileToUnZip">待解压的文件</param>
- /// <param name="zipedFolder">指定解压目标目录</param>
- /// <param name="password">密码</param>
- /// <returns>解压结果</returns>
- public static bool UnZip(string fileToUnZip, string zipedFolder, string password)
- {
- bool result = true;
- FileStream fs = null;
- ZipInputStream zipStream = null;
- ZipEntry ent = null;
- string fileName;
-
- if (!File.Exists(fileToUnZip))
- return false;
-
- if (!Directory.Exists(zipedFolder))
- Directory.CreateDirectory(zipedFolder);
-
- try
- {
- zipStream = new ZipInputStream(File.OpenRead(fileToUnZip));
- if (!string.IsNullOrEmpty(password)) zipStream.Password = password;
- while ((ent = zipStream.GetNextEntry()) != null)
- {
- if (!string.IsNullOrEmpty(ent.Name))
- {
- fileName = Path.Combine(zipedFolder, ent.Name);
- fileName = fileName.Replace('/', '\\');//change by Mr.HopeGi
-
- if (fileName.EndsWith("\\"))
- {
- Directory.CreateDirectory(fileName);
- continue;
- }
-
- fs = File.Create(fileName);
- int size = 2048;
- byte[] data = new byte[size];
- while (true)
- {
- size = zipStream.Read(data, 0, data.Length);
- if (size > 0)
- fs.Write(data, 0, data.Length);
- else
- break;
- }
- }
- }
- }
- catch
- {
- result = false;
- }
- finally
- {
- if (fs != null)
- {
- fs.Close();
- fs.Dispose();
- }
- if (zipStream != null)
- {
- zipStream.Close();
- zipStream.Dispose();
- }
- if (ent != null)
- {
- ent = null;
- }
- GC.Collect();
- GC.Collect(1);
- }
- return result;
- }
-
- /// <summary>
- /// 解压功能(解压压缩文件到指定目录)
- /// </summary>
- /// <param name="fileToUnZip">待解压的文件</param>
- /// <param name="zipedFolder">指定解压目标目录</param>
- /// <returns>解压结果</returns>
- public static bool UnZip(string fileToUnZip, string zipedFolder)
- {
- bool result = NewUnZip(fileToUnZip, zipedFolder, null, true);
- return result;
- }
-
- /// <summary>
- /// ZIP:解压一个zip文件
- /// </summary>
- /// <param name="ZipFile">需要解压的Zip文件(绝对路径)</param>
- /// <param name="TargetDirectory">解压到的目录</param>
- /// <param name="Password">解压密码</param>
- /// <param name="OverWrite">是否覆盖已存在的文件</param>
- public static bool NewUnZip(string ZipFile, string TargetDirectory, string Password, bool OverWrite = true)
- {
- try
- {
-
- //如果解压到的目录不存在,则报错
- if (!System.IO.Directory.Exists(TargetDirectory))
- {
- throw new System.IO.FileNotFoundException("指定的目录: " + TargetDirectory + " 不存在!");
- }
- //目录结尾
- if (!TargetDirectory.EndsWith("\\")) { TargetDirectory = TargetDirectory + "\\"; }
-
- using (ZipInputStream zipfiles = new ZipInputStream(File.OpenRead(ZipFile)))
- {
- zipfiles.Password = Password;
- ZipEntry theEntry;
-
- while ((theEntry = zipfiles.GetNextEntry()) != null)
- {
- string directoryName = "";
- string pathToZip = "";
- pathToZip = theEntry.Name;
-
- if (pathToZip != "")
- directoryName = Path.GetDirectoryName(pathToZip) + "\\";
-
- string fileName = Path.GetFileName(pathToZip);
-
- Directory.CreateDirectory(TargetDirectory + directoryName);
-
- if (fileName != "")
- {
- if ((File.Exists(TargetDirectory + directoryName + fileName) && OverWrite) || (!File.Exists(TargetDirectory + directoryName + fileName)))
- {
- try
- {
- using (FileStream streamWriter = File.Create(TargetDirectory + directoryName + fileName))
- {
- int size = 2048;
- byte[] data = new byte[2048];
- while (true)
- {
- size = zipfiles.Read(data, 0, data.Length);
-
- if (size > 0)
- streamWriter.Write(data, 0, size);
- else
- break;
- }
- streamWriter.Close();
- }
- }
- catch (Exception ex)
- {
- string message = ex.Message;
- //解压出错//若文件无损坏则可能为无法覆盖文件
- }
- }
- }
- }
-
- zipfiles.Close();
- }
- return true;
- }
- catch (Exception)
- {
- return false;
- }
- }
- #endregion
-
-
- #region 压缩文件
- /// <summary>
- /// 压缩文件
- /// </summary>
- /// <param name="fileNames">要打包的文件列表</param>
- /// <param name="GzipFileName">目标文件名</param>
- /// <param name="CompressionLevel">压缩品质级别(0~9)</param>
- /// <param name="deleteFile">是否删除原文件</param>
- public static void CompressFile(List<FileInfo> fileNames, string GzipFileName, int CompressionLevel, bool deleteFile)
- {
- ZipOutputStream s = new ZipOutputStream(File.Create(GzipFileName));
- try
- {
- s.SetLevel(CompressionLevel); //0 - store only to 9 - means best compression
- foreach (FileInfo file in fileNames)
- {
- FileStream fs = null;
- try
- {
- fs = file.Open(FileMode.Open, FileAccess.ReadWrite);
- }
- catch
- { continue; }
- // 方法二,将文件分批读入缓冲区
- byte[] data = new byte[2048];
- int size = 2048;
- ZipEntry entry = new ZipEntry(Path.GetFileName(file.Name));
- entry.DateTime = (file.CreationTime > file.LastWriteTime ? file.LastWriteTime : file.CreationTime);
- s.PutNextEntry(entry);
- while (true)
- {
- size = fs.Read(data, 0, size);
- if (size <= 0) break;
- s.Write(data, 0, size);
- }
- fs.Close();
- if (deleteFile)
- {
- file.Delete();
- }
- }
- }
- finally
- {
- s.Finish();
- s.Close();
- }
- }
- public static void CompressFile(string fileName, string GzipFileName, int CompressionLevel, bool deleteFile)
- {
- ZipOutputStream s = new ZipOutputStream(File.Create(GzipFileName));
- try
- {
- s.SetLevel(CompressionLevel); //0 - store only to 9 - means best compression
- FileInfo file = new FileInfo(fileName);
- FileStream fs = null;
- try
- {
- fs = file.Open(FileMode.Open, FileAccess.ReadWrite);
- }
- catch
- { return; }
- // 方法二,将文件分批读入缓冲区
- byte[] data = new byte[2048];
- int size = 2048;
- ZipEntry entry = new ZipEntry(Path.GetFileName(file.Name));
- entry.DateTime = (file.CreationTime > file.LastWriteTime ? file.LastWriteTime : file.CreationTime);
- s.PutNextEntry(entry);
- while (true)
- {
- size = fs.Read(data, 0, size);
- if (size <= 0) break;
- s.Write(data, 0, size);
- }
- fs.Close();
- if (deleteFile)
- {
- file.Delete();
- }
- }
- finally
- {
- s.Finish();
- s.Close();
- }
- }
- /// <summary>
- /// 压缩文件夹
- /// </summary>
- /// <param name="dirPath">要打包的文件夹</param>
- /// <param name="GzipFileName">目标文件名</param>
- /// <param name="CompressionLevel">压缩品质级别(0~9)</param>
- /// <param name="deleteDir">是否删除原文件夹</param>
- public static void CompressDirectory(string dirPath, string GzipFileName, int CompressionLevel, bool deleteDir)
- {
- //压缩文件为空时默认与压缩文件夹同一级目录
- if (GzipFileName == string.Empty)
- {
- GzipFileName = dirPath.Substring(dirPath.LastIndexOf("//") + 1);
- GzipFileName = dirPath.Substring(0, dirPath.LastIndexOf("//")) + "//" + GzipFileName + ".zip";
- }
- //if (Path.GetExtension(GzipFileName) != ".zip")
- //{
- // GzipFileName = GzipFileName + ".zip";
- //}
- using (ZipOutputStream zipoutputstream = new ZipOutputStream(File.Create(GzipFileName)))
- {
- zipoutputstream.SetLevel(CompressionLevel);
- Crc32 crc = new Crc32();
- Dictionary<string, DateTime> fileList = GetAllFies(dirPath);
- foreach (KeyValuePair<string, DateTime> item in fileList)
- {
- FileStream fs = File.OpenRead(item.Key.ToString());
- byte[] buffer = new byte[fs.Length];
- fs.Read(buffer, 0, buffer.Length);
- ZipEntry entry = new ZipEntry(item.Key.Substring(dirPath.Length));
- entry.DateTime = item.Value;
- entry.Size = fs.Length;
- fs.Close();
- crc.Reset();
- crc.Update(buffer);
- entry.Crc = crc.Value;
- zipoutputstream.PutNextEntry(entry);
- zipoutputstream.Write(buffer, 0, buffer.Length);
- }
- }
- if (deleteDir)
- {
- Directory.Delete(dirPath, true);
- }
- }
- /// <summary>
- /// 获取所有文件
- /// </summary>
- /// <returns></returns>
- private static Dictionary<string, DateTime> GetAllFies(string dir)
- {
- Dictionary<string, DateTime> FilesList = new Dictionary<string, DateTime>();
- DirectoryInfo fileDire = new DirectoryInfo(dir);
- if (!fileDire.Exists)
- {
- throw new System.IO.FileNotFoundException("目录:" + fileDire.FullName + "没有找到!");
- }
- GetAllDirFiles(fileDire, FilesList);
- GetAllDirsFiles(fileDire.GetDirectories(), FilesList);
- return FilesList;
- }
- /// <summary>
- /// 获取一个文件夹下的所有文件夹里的文件
- /// </summary>
- /// <param name="dirs"></param>
- /// <param name="filesList"></param>
- private static void GetAllDirsFiles(DirectoryInfo[] dirs, Dictionary<string, DateTime> filesList)
- {
- foreach (DirectoryInfo dir in dirs)
- {
- foreach (FileInfo file in dir.GetFiles("*.*"))
- {
- filesList.Add(file.FullName, file.LastWriteTime);
- }
- GetAllDirsFiles(dir.GetDirectories(), filesList);
- }
- }
- /// <summary>
- /// 获取一个文件夹下的文件
- /// </summary>
- /// <param name="dir">目录名称</param>
- /// <param name="filesList">文件列表HastTable</param>
- private static void GetAllDirFiles(DirectoryInfo dir, Dictionary<string, DateTime> filesList)
- {
- foreach (FileInfo file in dir.GetFiles("*.*"))
- {
- filesList.Add(file.FullName, file.LastWriteTime);
- }
- }
- #endregion
-
- #region 解压缩文件
- /// <summary>
- /// 解压缩文件
- /// </summary>
- /// <param name="GzipFile">压缩包文件名</param>
- /// <param name="targetPath">解压缩目标路径</param>
- public static void Decompress(string GzipFile, string targetPath)
- {
- //string directoryName = Path.GetDirectoryName(targetPath + "//") + "//";
- string directoryName = targetPath;
- if (!Directory.Exists(directoryName)) Directory.CreateDirectory(directoryName);//生成解压目录
- string CurrentDirectory = directoryName;
- byte[] data = new byte[2048];
- int size = 2048;
- ZipEntry theEntry = null;
- using (ZipInputStream s = new ZipInputStream(File.OpenRead(GzipFile)))
- {
- while ((theEntry = s.GetNextEntry()) != null)
- {
- if (theEntry.IsDirectory)
- {// 该结点是目录
- if (!Directory.Exists(CurrentDirectory + theEntry.Name)) Directory.CreateDirectory(CurrentDirectory + theEntry.Name);
- }
- else
- {
- if (theEntry.Name != String.Empty)
- {
- // 检查多级目录是否存在
- if (theEntry.Name.Contains("\\"))
- {
- string parentDirPath = theEntry.Name.Remove(theEntry.Name.LastIndexOf("\\") + 1);
- if (!Directory.Exists(parentDirPath))
- {
- Directory.CreateDirectory(CurrentDirectory + parentDirPath);
- }
- }
-
- //解压文件到指定的目录
- using (FileStream streamWriter = File.Create(CurrentDirectory + theEntry.Name))
- {
- while (true)
- {
- size = s.Read(data, 0, data.Length);
- if (size <= 0) break;
- streamWriter.Write(data, 0, size);
- }
- streamWriter.Close();
- }
- }
- }
- }
- s.Close();
- }
- }
- #endregion
-
- }
- }
|