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)$";//排除的文件

  

posted @ 2019-05-24 17:20  石shi  阅读(1272)  评论(0编辑  收藏  举报