C#解壓、壓縮高級用法

壓縮:(能夠吧要排除的文件去掉)java

       /// <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;
        }

  壓縮排除文件夾的調用:blog

excludePathReg.Add("\\\\static\\\\katex\\\\.+");

  排除的文件:遞歸

string excludeFileReg = "(\\.mp4|\\.avi|\\.rmvb|\\.divx|\\.asf|\\.rm|\\.mpg|\\.mpeg|\\.mpe|\\.wmv|\\.mkv|\\.vob|\\.txt|\\.bat|\\.TXT)$";//排除的文件
相關文章
相關標籤/搜索