using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading.Tasks; using ICSharpCode.SharpZipLib.Checksum; using ICSharpCode.SharpZipLib.Zip; // ReSharper disable All namespace Team.Utility { public class ZipUtility { /// /// ZIP:压缩单个文件 /// add yuangang by 2016-06-13 /// /// 需要压缩的文件(绝对路径) /// 压缩后的文件路径(绝对路径) /// 压缩后的文件名称(文件名,默认 同源文件同名) /// 压缩等级(0 无 - 9 最高,默认 5) /// 缓存大小(每次写入文件大小,默认 2048) /// 是否加密(默认 加密) public static void Zip(string fileToZip, string zipPath, string zippedFileName = "", int compressionLevel = 5, int blockSize = 2048, bool isEncrypt = true) { //如果文件没有找到,则报错 if (!File.Exists(fileToZip)) { throw new FileNotFoundException("指定要压缩的文件: " + fileToZip + " 不存在!"); } //文件名称(默认同源文件名称相同) var zipFileName = string.IsNullOrEmpty(zippedFileName) ? zipPath + "\\" + new FileInfo(fileToZip).Name.Substring(0, new FileInfo(fileToZip).Name.LastIndexOf('.')) + ".zip" : zipPath + "\\" + zippedFileName + ".zip"; using (var zipFile = File.Create(zipFileName)) { using (var zipStream = new ZipOutputStream(zipFile)) { using (var streamToZip = new FileStream(fileToZip, FileMode.Open, FileAccess.Read)) { var fileName = fileToZip.Substring(fileToZip.LastIndexOf("\\", StringComparison.Ordinal) + 1); var zipEntry = new ZipEntry(fileName); if (isEncrypt) { //压缩文件加密 zipStream.Password = "123"; } zipStream.PutNextEntry(zipEntry); //设置压缩级别 zipStream.SetLevel(compressionLevel); //缓存大小 var buffer = new byte[blockSize]; int sizeRead; do { sizeRead = streamToZip.Read(buffer, 0, buffer.Length); zipStream.Write(buffer, 0, sizeRead); } while (sizeRead > 0); streamToZip.Close(); } zipStream.Finish(); zipStream.Close(); } zipFile.Close(); } } /// /// ZIP:压缩文件夹 /// /// /// 需要压缩的文件夹(绝对路径) /// 压缩后的文件路径(绝对路径) /// 压缩后的文件名称(文件名,默认 同源文件夹同名) /// 是否加密(默认 加密) public static void ZipDirectory(string directoryToZip, string zipedPath, string zipedFileName = "", bool isEncrypt = true) { //如果目录不存在,则报错 if (!Directory.Exists(directoryToZip)) { throw new FileNotFoundException("指定的目录: " + directoryToZip + " 不存在!"); } //文件名称(默认同源文件名称相同) var zipFileName = string.IsNullOrEmpty(zipedFileName) ? zipedPath + "\\" + new DirectoryInfo(directoryToZip).Name + ".zip" : zipedPath + "\\" + zipedFileName + ".zip"; using (var zipFile = File.Create(zipFileName)) { using (var s = new ZipOutputStream(zipFile)) { if (isEncrypt) { //压缩文件加密 s.Password = "123"; } ZipSetp(directoryToZip, s, ""); } } } /// /// ZIP:压缩文件夹 /// /// 需要压缩的文件夹(绝对路径) /// 压缩后的文件路径(绝对路径) /// 压缩后的文件名称(文件名,默认 同源文件夹同名) /// 是否加密(默认 加密) public static async Task ZipDirectoryAsync(string directoryToZip, string zipedPath, string zipedFileName = "", bool isEncrypt = true) { //如果目录不存在,则报错 if (!Directory.Exists(directoryToZip)) { throw new FileNotFoundException("指定的目录: " + directoryToZip + " 不存在!"); } //文件名称(默认同源文件名称相同) var zipFileName = string.IsNullOrEmpty(zipedFileName) ? zipedPath + "\\" + new DirectoryInfo(directoryToZip).Name + ".zip" : zipedPath + "\\" + zipedFileName + ".zip"; using var zipFile = File.Create(zipFileName); using var s = new ZipOutputStream(zipFile); if (isEncrypt) { //压缩文件加密 s.Password = "123"; } await ZipSetpAsync(directoryToZip, s, ""); } /// /// 压缩多层目录 /// /// The directory. /// The ziped file. public static void ZipFileDirectory(string strDirectory, string zipedFile) { using (System.IO.FileStream ZipFile = System.IO.File.Create(zipedFile)) { using (ZipOutputStream s = new ZipOutputStream(ZipFile)) { ZipSetp(strDirectory, s, ""); } } } public static void ZipFiles(List filesPath,string zipedPath,string zipedFileName = "", bool isEncrypt = true) { //如果目录不存在,则报错 foreach (var filePath in filesPath) { throw new FileNotFoundException("指定的目录: " + filePath + " 不存在!"); } //文件名称(默认同源文件名称相同) var zipFileName = string.IsNullOrEmpty(zipedFileName) ? zipedPath + "\\" + new DirectoryInfo(filesPath.First()).Name + ".zip" : zipedPath + "\\" + zipedFileName + ".zip"; using (var zipFile = File.Create(zipFileName)) { using (var s = new ZipOutputStream(zipFile)) { if (isEncrypt) { //压缩文件加密 s.Password = "123"; } ZipSetp(filesPath.First(), s, ""); } } } public static async Task ZipFilesAsync(List filesPathes, string zipedPath, string zipedFileName = "", int compressionLevel = 5, int blockSize = 2048, bool isEncrypt = true) { foreach (var filesPath in filesPathes) { //如果文件没有找到,则报错 if (!File.Exists(filesPath)) { throw new FileNotFoundException("指定要压缩的文件: " + filesPath + " 不存在!"); } } //文件名称(默认同源文件名称相同) var zipFileName = string.IsNullOrEmpty(zipedFileName) ? zipedPath + "\\" + new FileInfo(zipedPath).Name.Substring(0, new FileInfo(zipedPath).Name.LastIndexOf('.')) + ".zip" : zipedPath + "\\" + zipedFileName + ".zip"; using (var zipFile = File.Create(zipFileName)) { using (var zipStream = new ZipOutputStream(zipFile)) { foreach (var filesPath in filesPathes) { using (var streamToZip = new FileStream(filesPath, FileMode.Open, FileAccess.Read)) { var fileName = filesPath.Substring(filesPath.LastIndexOf("\\", StringComparison.Ordinal) + 1); var zipEntry = new ZipEntry(fileName); if (isEncrypt) { //压缩文件加密 zipStream.Password = "123"; } zipStream.PutNextEntry(zipEntry); //设置压缩级别 zipStream.SetLevel(compressionLevel); //缓存大小 var buffer = new byte[blockSize]; int sizeRead; do { sizeRead = await streamToZip.ReadAsync(buffer, 0, buffer.Length); await zipStream.WriteAsync(buffer, 0, sizeRead); } while (sizeRead > 0); } } } } } /// /// 递归遍历目录 /// add yuangang by 2016-06-13 /// private static void ZipSetp(string strDirectory, ZipOutputStream s, string parentPath) { if (strDirectory[strDirectory.Length - 1] != Path.DirectorySeparatorChar) { strDirectory += Path.DirectorySeparatorChar; } var crc = new Crc32(); var fileNames = Directory.GetFileSystemEntries(strDirectory); foreach (var file in fileNames) // 遍历所有的文件和目录 { if (Directory.Exists(file)) // 先当作目录处理如果存在这个目录就递归Copy该目录下面的文件 { var pPath = parentPath; pPath += file.Substring(file.LastIndexOf("\\", StringComparison.Ordinal) + 1); pPath += "\\"; ZipSetp(file, s, pPath); } else // 否则直接压缩文件 { //打开压缩文件 using (var fs = File.OpenRead(file)) { var buffer = new byte[fs.Length]; fs.Read(buffer, 0, buffer.Length); var fileName = parentPath + file.Substring(file.LastIndexOf("\\", StringComparison.Ordinal) + 1); var entry = new ZipEntry(fileName); entry.DateTime = DateTime.Now; entry.Size = fs.Length; fs.Close(); crc.Reset(); crc.Update(buffer); entry.Crc = crc.Value; s.PutNextEntry(entry); s.Write(buffer, 0, buffer.Length); } } } } private static async Task ZipSetpAsync(string strDirectory, ZipOutputStream s, string parentPath) { if (strDirectory[strDirectory.Length - 1] != Path.DirectorySeparatorChar) { strDirectory += Path.DirectorySeparatorChar; } var crc = new Crc32(); var fileNames = Directory.GetFileSystemEntries(strDirectory); foreach (var file in fileNames) // 遍历所有的文件和目录 { if (Directory.Exists(file)) // 先当作目录处理如果存在这个目录就递归Copy该目录下面的文件 { var pPath = parentPath; pPath += file.Substring(file.LastIndexOf("\\", StringComparison.Ordinal) + 1); pPath += "\\"; ZipSetp(file, s, pPath); } else // 否则直接压缩文件 { //打开压缩文件 using var fs = File.OpenRead(file); var buffer = new byte[fs.Length]; await fs.ReadAsync(buffer, 0, buffer.Length); var fileName = parentPath + file.Substring(file.LastIndexOf("\\", StringComparison.Ordinal) + 1); var entry = new ZipEntry(fileName); entry.DateTime = DateTime.Now; entry.Size = fs.Length; crc.Reset(); crc.Update(buffer); entry.Crc = crc.Value; s.PutNextEntry(entry); await s.WriteAsync(buffer, 0, buffer.Length); } } } /// /// ZIP:解压一个zip文件 /// add yuangang by 2016-06-13 /// /// 需要解压的Zip文件(绝对路径) /// 解压到的目录 /// 解压密码 /// 是否覆盖已存在的文件 public static void UnZip(string zipFile, string targetDirectory, string password, bool overWrite = true) { //如果解压到的目录不存在,则报错 if (!Directory.Exists(targetDirectory)) { throw new FileNotFoundException("指定的目录: " + targetDirectory + " 不存在!"); } //目录结尾 if (!targetDirectory.EndsWith("\\")) { targetDirectory = targetDirectory + "\\"; } using (var zipFiles = new ZipInputStream(File.OpenRead(zipFile))) { zipFiles.Password = password; ZipEntry theEntry; while ((theEntry = zipFiles.GetNextEntry()) != null) { var directoryName = ""; var pathToZip = theEntry.Name; if (pathToZip != "") directoryName = Path.GetDirectoryName(pathToZip) + "\\"; var fileName = Path.GetFileName(pathToZip); Directory.CreateDirectory(targetDirectory + directoryName); if (fileName == "") continue; if ((!File.Exists(targetDirectory + directoryName + fileName) || !overWrite) && (File.Exists(targetDirectory + directoryName + fileName))) continue; using (var streamWriter = File.Create(targetDirectory + directoryName + fileName)) { var data = new byte[2048]; while (true) { var size = zipFiles.Read(data, 0, data.Length); if (size > 0) streamWriter.Write(data, 0, size); else break; } streamWriter.Close(); } } zipFiles.Close(); } } } }