C#解压、压缩高级用法
压缩:(可以吧要排除的文件去掉)
/// <summary> /// 压缩文件夹 /// </summary> /// <param name="folder"></param> /// <param name="zipedFileName"></param> /// <param name="compressionLevel">压缩率0(无压缩)9(压缩率最高)</param> public static void ZipDir(string zipedFileName, string folder, string dirEntryPrefix = null, string excludePathReg = null, int compressionLevel = 4) { if (Path.GetExtension(zipedFileName) != ".zip") { zipedFileName = zipedFileName + ".zip"; } ZipDir(zipedFileName, new string[] { folder }, new string[] { dirEntryPrefix }, new string[] { excludePathReg }, compressionLevel); } public static void ZipDir(string zipedFileName, string[] folders, string[] dirEntryPrefixs = null, string[] excludePathRegs = null, int compressionLevel = 4) { if (Path.GetExtension(zipedFileName) != ".zip") { zipedFileName = zipedFileName + ".zip"; } if (string.IsNullOrEmpty(zipedFileName) || folders == null) return; if (dirEntryPrefixs != null && folders.Length != dirEntryPrefixs.Length) throw new Exception("数组个数不一致"); if (excludePathRegs != null && folders.Length != excludePathRegs.Length) throw new Exception("数组个数不一致"); FileUtils.CreateDirectoryIfNotExists(Path.GetDirectoryName(zipedFileName)); using (var zipoutputstream = new ZipOutputStream(File.Create(zipedFileName))) { zipoutputstream.SetLevel(compressionLevel); Crc32 crc = new Crc32(); for (int i = 0; i < folders.Length; i++) { string folder = folders[i]; folder = Path.GetFullPath(folder); //先将文件夹名称标准化 string excludePathReg = null; if (excludePathRegs != null) excludePathReg = excludePathRegs[i]; string dirEntryPrefix = null; if (dirEntryPrefixs != null) dirEntryPrefix = dirEntryPrefixs[i]; List<FileInfo> allFiles = GetAllFileEntries(folder, excludePathReg); if (allFiles == null) continue; foreach (FileInfo fileInfo in allFiles) { //读取文件内容 //FileStream fs = new FileStream(fileInfo.FullName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); //byte[] buffer = new byte[fs.Length]; //fs.Read(buffer, 0, buffer.Length); //fs.Close(); byte[] buffer = File.ReadAllBytes(fileInfo.FullName); //生成路径 string entryPath; if (File.Exists(folder)) entryPath = fileInfo.Name; //但如果“文件夹”本身就是独立的文件,则直接取文件名 else entryPath = fileInfo.FullName.Substring(folder.Length + 1); //全路径减去原文件夹的路径 if (!string.IsNullOrEmpty(dirEntryPrefix)) { entryPath = Path.Combine(dirEntryPrefix, entryPath); //加上前缀 } entryPath = entryPath.Replace('\\', '/'); ZipEntry entry = new ZipEntry(entryPath); entry.DateTime = fileInfo.LastWriteTime; entry.Size = fileInfo.Length; crc.Reset(); crc.Update(buffer); entry.Crc = crc.Value; zipoutputstream.PutNextEntry(entry); zipoutputstream.Write(buffer, 0, buffer.Length); } } } } public static List<FileInfo> GetAllFileEntries(string folder, string excludePathReg = null) { if (string.IsNullOrEmpty(folder)) return null; if (File.Exists(folder)) //如果是文件,则直接返回该文件 { return new List<FileInfo>() { new FileInfo(folder) }; } //一般情况下是数组 DirectoryInfo dirInfo = new DirectoryInfo(folder); if (!dirInfo.Exists) return null; List<FileInfo> result = new List<FileInfo>(); //先遍历下面所有的文件 foreach (FileInfo fileInfo in dirInfo.GetFiles()) { string fileName = fileInfo.Name; if (fileName == ".DS_Store" || fileName.StartsWith("._")) continue; // mac系统下的系统文件直接忽略 if (!string.IsNullOrEmpty(excludePathReg))//排除一些 { if (Regex.IsMatch(fileInfo.FullName, excludePathReg)) continue; } result.Add(fileInfo); } //再递归遍历下面所有的子文件夹 foreach (DirectoryInfo subDir in dirInfo.GetDirectories()) { result.AddRange(GetAllFileEntries(subDir.FullName, excludePathReg)); } return result; }
解压:(可以对要解压的文件进行操作,转换在lambda中加方法中就行)
public static int UnZip(string zipFilePath, string unZipDir) { return UnZip(zipFilePath, unZipDir, false, null, null); } public static int UnZipGGBforBook(string zipFilePath, string unZipDir) { return UnZip(zipFilePath, unZipDir, true, ConvertGGBtoBase64, fileName => fileName.Replace(".ggb", ".js")); } private static Stream ConvertGGBtoBase64(MemoryStream stream) { //将GGB内容转成base64 //stream.Seek(0, SeekOrigin.Begin); //int len = (int)stream.Length; //byte[] buffer = new byte[len]; //stream.Read(buffer, 0, len); byte[] buffer = stream.ToArray(); string base64 = Convert.ToBase64String(buffer); string content = "var 1111=\"" + base64 +"\";"; byte[] contentBytes = Encoding.UTF8.GetBytes(content); //MemoryStream memory = new MemoryStream(); //memory.Write(contentBytes, 0, contentBytes.Length); MemoryStream memory = new MemoryStream(contentBytes); return memory; } /// <summary> /// 功能:解压zip格式的文件。 /// </summary> /// <param name="zipFilePath">压缩文件路径</param> /// <param name="unZipDir">解压文件存放路径,为空时默认与压缩文件同一级目录下,跟压缩文件同名的文件夹</param> /// <param name="boolBase64">是否生成base64 /// <returns>解压是否成功</returns> public static int UnZip(string zipFilePath, string unZipDir, bool ignoreTargetRootDir, Func<MemoryStream,Stream> contentConverter, Func<string, string> fileNameConverter) { if (string.IsNullOrEmpty(zipFilePath)) return 0; if (!File.Exists(zipFilePath)) return 0; //解压文件夹为空时默认与压缩文件同一级目录下,跟压缩文件同名的文件夹 if (unZipDir == string.Empty) unZipDir = zipFilePath.Replace(Path.GetFileName(zipFilePath), Path.GetFileNameWithoutExtension(zipFilePath)); if (!unZipDir.EndsWith("\\")) unZipDir += "\\"; if (!Directory.Exists(unZipDir)) Directory.CreateDirectory(unZipDir); int fileCnt = 0; //解压的文件数(不含文件夹) using (var sourceStream = new ZipInputStream(File.OpenRead(zipFilePath))) { ZipEntry entry; while ((entry = sourceStream.GetNextEntry()) != null) { string name = entry.Name; if (string.IsNullOrEmpty(name)) continue; name = name.Replace("/", "\\"); if (ignoreTargetRootDir) { name = name.Substring(name.IndexOf("\\") + 1); //去掉目标文件所带的根目录,如"书名" } if (string.IsNullOrEmpty(name)) continue; string targetName = unZipDir + name; //要放入的目标文件 //删除不在这个地方考虑 //if (targetName.EndsWith("geogebra\\"))//把原始文件下面的先删除 //{ // DeleteDirectory(targetName, null); //} //string targetDir = Path.GetDirectoryName(targetName); //如果是文件夹,则创建文件夹 if (name.EndsWith("\\")) { Directory.CreateDirectory(targetName); continue; } //如果是文件,则输出到目标中 //文件名可能需要转换 if (fileNameConverter != null) { targetName = fileNameConverter(targetName); if (string.IsNullOrEmpty(targetName)) continue; //如果得到的文件名为空,则不处理 } MemoryStream memoryStream = new MemoryStream(); sourceStream.CopyTo(memoryStream); //byte[] data = new byte[2048]; //while (true) //{ // int size = sourceStream.Read(data, 0, data.Length); // if (size == 0) break; // memoryStream.Write(data, 0, size); //} //如果需要转换流 Stream convertedStream = memoryStream; if (contentConverter != null) { convertedStream = contentConverter(memoryStream); } FileStream targetStream = File.Create(targetName); convertedStream.Seek(0, SeekOrigin.Begin); convertedStream.CopyTo(targetStream); targetStream.Close(); convertedStream.Close(); if (memoryStream != convertedStream) memoryStream.Close(); fileCnt++; } } return fileCnt; }
压缩排除文件夹的调用:
excludePathReg.Add("\\\\static\\\\katex\\\\.+");
排除的文件:
string excludeFileReg = "(\\.mp4|\\.avi|\\.rmvb|\\.divx|\\.asf|\\.rm|\\.mpg|\\.mpeg|\\.mpe|\\.wmv|\\.mkv|\\.vob|\\.txt|\\.bat|\\.TXT)$";//排除的文件