using ICSharpCode.SharpZipLib.Checksum; using ICSharpCode.SharpZipLib.Zip; using System.Text; namespace YLErp.Helpers { public static class ZipHelper { static ZipHelper() { Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); ZipStrings.CodePage = Encoding.GetEncoding("gb2312").CodePage; } /// /// 压缩文件目录 /// /// /// public static void ZipDirectory(string sourceDir, string targetZipFile) { if (sourceDir[sourceDir.Length - 1] != Path.DirectorySeparatorChar) { sourceDir += Path.DirectorySeparatorChar; } var outstream = new ZipOutputStream(File.Create(targetZipFile)); outstream.SetLevel(6); ZipDirectory(sourceDir, outstream, sourceDir); outstream.Finish(); outstream.Close(); } /// /// 压缩文件目录 /// /// /// /// public static void ZipDirectory(string sourceDir, ZipOutputStream outStream, string staticFile) { if (sourceDir[sourceDir.Length - 1] != Path.DirectorySeparatorChar) { sourceDir += Path.DirectorySeparatorChar; } //获取指定目录下所有文件和子目录文件名称 var filenames = Directory.GetFileSystemEntries(sourceDir); zip(filenames, outStream, staticFile); } public static void zipFile(string strFile, string strZip) { var len = strFile.Length; var strlen = strFile[len - 1]; if (strFile[strFile.Length - 1] != Path.DirectorySeparatorChar) { strFile += Path.DirectorySeparatorChar; } var outstream = new ZipOutputStream(File.Create(strZip)); outstream.SetLevel(6); zip(strFile, outstream, strFile); outstream.Finish(); outstream.Close(); } public static void zipOnlyFile(string strFile, string strZip, string password = "") { var outstream = new ZipOutputStream(File.Create(strZip)); outstream.SetLevel(6); if (!string.IsNullOrWhiteSpace(password)) { outstream.Password = password; } string[] filenames = new string[] { strFile }; zip(filenames, outstream, strFile); outstream.Finish(); outstream.Close(); } public static void zip(string strFile, ZipOutputStream outstream, string staticFile) { if (strFile[strFile.Length - 1] != Path.DirectorySeparatorChar) { strFile += Path.DirectorySeparatorChar; } var crc = new Crc32(); //获取指定目录下所有文件和子目录文件名称 string[] filenames = Directory.GetFileSystemEntries(strFile); zip(filenames, outstream, staticFile); } public static void zipFiles(string[] filenames, string parentDirectory, out byte[] buffer) { var stream = new MemoryStream(); var outstream = new ZipOutputStream(stream); outstream.SetLevel(6); zip(filenames, outstream, parentDirectory); outstream.Finish(); stream.Seek(0, SeekOrigin.Begin); buffer = new byte[stream.Length]; stream.Read(buffer, 0, buffer.Length); outstream.Close(); } /// /// 压缩多个文件 /// /// 要进行压缩的文件集合 /// 压缩目标文件 public static void ZipFilesWithLevel(List sourceFiles, string targetZipFile, int compressionLevel) { foreach (var fileToZip in sourceFiles) { //如果文件没有找到,则报错 if (!File.Exists(fileToZip)) { throw new FileNotFoundException("指定要压缩的文件: " + fileToZip + " 不存在!"); } } using var ZipFile = File.Create(targetZipFile); using var ZipStream = new ZipOutputStream(ZipFile); foreach (var fileToZip in sourceFiles) { var fileName = fileToZip.Substring(fileToZip.LastIndexOf(Path.DirectorySeparatorChar)); using var fs = File.OpenRead(fileToZip); var buffer = new byte[fs.Length]; fs.Read(buffer, 0, buffer.Length); fs.Close(); var ZipEntry = new ZipEntry(fileName); ZipStream.PutNextEntry(ZipEntry); ZipStream.SetLevel(compressionLevel); ZipStream.Write(buffer, 0, buffer.Length); } ZipStream.Finish(); ZipStream.Close(); } private static void zip(string[] filenames, ZipOutputStream outstream, string staticFile) { var crc = new Crc32(); //遍历文件 foreach (var file in filenames) { if (Directory.Exists(file)) { zip(file, outstream, staticFile); } //否则,直接压缩文件 else { //打开文件 var fs = File.OpenRead(file); //定义缓存区对象 var buffer = new byte[fs.Length]; //通过字符流,读取文件 fs.Read(buffer, 0, buffer.Length); //得到目录下的文件(比如:D:\Debug1\test),test //这里是为了得到压缩文件内的目录结构; string tempfile = file.Substring(staticFile.LastIndexOf(Path.DirectorySeparatorChar) + 1); //string tempfile = Path.GetFileName(file); ZipEntry entry = new ZipEntry(tempfile) { DateTime = DateTime.Now, Size = fs.Length }; fs.Close(); crc.Reset(); crc.Update(buffer); entry.Crc = crc.Value; outstream.PutNextEntry(entry); //写文件 outstream.Write(buffer, 0, buffer.Length); } } } public static string unZipFile(string TargetFile, string fileDir, out string msg) { LogFactory.GetLogger("UploadEventReportFile").Info($"准备解压{fileDir}->{TargetFile}"); msg = ""; //读取压缩文件(zip文件),准备解压缩 using (var inputstream = new ZipInputStream(File.OpenRead(TargetFile.Trim()))) { ZipEntry entry; var pathName = Path.GetFileNameWithoutExtension(TargetFile); fileDir = Path.Combine(fileDir, pathName); LogFactory.GetLogger("UploadEventReportFile").Info($"准备解压{fileDir}"); var path = fileDir; //压缩文件内第一层子目录 var rootDir = ""; //压缩文件内子目录 var dir = ""; var fileName = ""; while ((entry = inputstream.GetNextEntry()) != null) { if (!string.IsNullOrWhiteSpace(entry.Name)) { //得到根目录下的第一级子文件夹的名称 rootDir = Path.GetDirectoryName(entry.Name); if (rootDir.IndexOf(Path.DirectorySeparatorChar) >= 0) { rootDir = rootDir.Substring(0, rootDir.IndexOf(Path.DirectorySeparatorChar) + 1); } //得到根目录下的第一级子文件夹下的子文件夹名称 dir = Path.GetDirectoryName(entry.Name); //根目录下的文件名称 fileName = Path.GetFileName(entry.Name); } LogFactory.GetLogger("UploadEventReportFile").Info($"根目录下的文件名称{fileName}"); //创建根目录下的子文件夹,不限制级别 if (!Directory.Exists(fileDir + Path.DirectorySeparatorChar + dir)) { path = fileDir + Path.DirectorySeparatorChar + dir; //在指定的路径创建文件夹 Directory.CreateDirectory(path); LogFactory.GetLogger("UploadEventReportFile").Info($"在指定的路径创建文件夹{path}"); } if (dir == "" && fileName != "") { //根目录下的文件 path = fileDir; } else if (dir != "" && fileName != "") { //根目录下的第一级子文件夹下的文件 if (dir.IndexOf(Path.DirectorySeparatorChar) > 0) { //指定文件保存路径 path = fileDir + Path.DirectorySeparatorChar + dir; LogFactory.GetLogger("UploadEventReportFile").Info($"指定文件保存路径{path}"); } } if (dir == rootDir) { //判断是不是需要保存在根目录下的文件 path = fileDir + Path.DirectorySeparatorChar + rootDir; } //以下为解压zip文件的基本步骤 //基本思路:遍历压缩文件里的所有文件,创建一个相同的文件 if (fileName != string.Empty) { var fs = File.Create(path + Path.DirectorySeparatorChar + fileName); LogFactory.GetLogger("UploadEventReportFile").Info($"遍历压缩文件里的所有文件{fs.Name}"); var size = 2048; var data = new byte[2048]; while (true) { size = inputstream.Read(data, 0, data.Length); if (size > 0) { fs.Write(data, 0, size); } else { break; } } fs.Close(); } } } msg = "解压成功!"; return fileDir; } } }