zoukankan      html  css  js  c++  java
  • 使用SharpZipLib实现文件压缩、解压

    接口

    public interface IUnZip
    {
        /// <summary>   
        /// 功能:解压zip格式的文件。   
        /// </summary>   
        /// <param name="zipFilePath">压缩文件路径</param>   
        /// <param name="unZipDir">解压文件存放路径,为空时默认与压缩文件同一级目录下,跟压缩文件同名的文件夹</param>   
        /// <param name="password">压缩包密码</param>
        /// <returns>解压后文件所在的文件夹</returns>
        string UnZipFile(string zipFilePath, string unZipDir = null, string password = null);
    }
    
    public interface IZip
    {
        /// <summary>
        /// 将选定的文件压入一个目标zip中
        /// </summary>
        /// <param name="list">选定的文件/文件夹(路径的集合)</param>
        /// <param name="targetFileName">压缩后得到的zip保存路径</param> 
        /// <param name="password">压缩包密码</param>
        /// <param name="overwrite">如果Zip文件已存在,是否覆盖</param> 
        /// <param name="level">压缩等级0—9</param>
        /// <returns>压缩包路径</returns>
        void Compress(List<string> list, string targetFileName, string password = null, bool overwrite = true, int level = 9);
    
        /// <summary>
        /// 将选定的文件压入一个目标zip中
        /// </summary>
        /// <param name="fileOrDir">选定的文件/文件夹</param>
        /// <param name="targetFileName">压缩后得到的zip保存路径</param>
        /// <param name="password">压缩包密码</param>
        /// <param name="overwrite">如果Zip文件已存在,是否覆盖</param>  
        /// <param name="level">压缩等级0—9</param>
        /// <returns>压缩包路径</returns>
        void Compress(string fileOrDir, string targetFileName, string password = null, bool overwrite = true, int level = 9);
    }
    
    public interface IZipHelper:IZip,IUnZip
    {
    }
    

    实现

       public class ZipHelper : IZipHelper
    {
        #region 压缩文件
    
        /// <inheritdoc/>
        public void Compress(string fileOrDir, string targetFileName, string password = null, bool overwrite = true, int level = 9)
        {
            List<string> list = new List<string> { fileOrDir };
            Compress(list, targetFileName, password, overwrite,level);
        }
    
        /// <inheritdoc/>
        public void Compress(List<string> list, string targetFileName, string password = null, bool overwrite = true,int level = 9)
        {
            CheckForCompress(list, targetFileName, overwrite);
    
            //如果已经存在目标文件,删除
            if (File.Exists(targetFileName))
            {
                File.Delete(targetFileName);
            }
    
            ZipOutputStream zips = null;
            FileStream fileStream = null;
            try
            {
                fileStream = File.Create(targetFileName);
                zips = new ZipOutputStream(fileStream);
                zips.SetLevel(level % 10);      //压缩等级
                zips.Password = password;
                foreach (string dir in list)
                {
                    if (File.Exists(dir))
                    {
                        AddFile("",dir, zips);
                    }
                    else
                    {
                        CompressFolder("", dir, zips);
                    }
                }
                zips.Finish();
            }
            catch { throw; }
            finally
            {
                if(fileStream!= null)
                {
                    fileStream.Close();
                    fileStream.Dispose();
                }
                if(zips!= null)
                {
                    zips.Close();
                    zips.Dispose();
                }
            }
        }
    
        #region private
        private void CheckForCompress(List<string> files, string targetFileName, bool overwrite)
        {
            //因为files可能来自不同的文件夹,所以不方便自动提供一个默认文件夹,需要提供
            if (!overwrite && File.Exists(targetFileName))
            {
                throw new Exception("目标zip文件已存在!");
            }
    
            //待压入的文件或文件夹需要真实存在
            foreach (var item in files)
            {
                if (!File.Exists(item) && !Directory.Exists(item))
                {
                    throw new Exception($"文件/文件夹【{item}】不存在!");
                }
            }
    
            //不能有同名的文件/文件夹
            Dictionary<string, string> dic = new Dictionary<string, string>();
            foreach (var item in files)
            {
                string item_ = item.TrimEnd('/', '\');
                string fileName = Path.GetFileName(item_);
                if (dic.ContainsKey(fileName))
                {
                    throw new Exception($"选中的文件/文件夹中存在同名冲突:【{dic[fileName]}】,【{item_}】");
                }
                else
                {
                    dic[fileName] = item_;
                }
            }
        }
        
        private void AddFile(string orignalDir, string file, ZipOutputStream zips)
        {  
            //文件
            FileStream StreamToZip = null;
            try
            {
                //加入ZIP文件条目(为压缩文件流提供一个容器)
                StreamToZip = new FileStream(file, FileMode.Open, FileAccess.Read);
                string fileName = Path.GetFileName(file);
                if (!string.IsNullOrEmpty(orignalDir))
                {
                    fileName = orignalDir + Path.DirectorySeparatorChar + fileName;
                }
                ZipEntry z = new ZipEntry(fileName);
                zips.PutNextEntry(z);
    
                //写入文件流
                int pack = 10240; //10Kb
                byte[] buffer = new byte[pack];
    
                int size = StreamToZip.Read(buffer, 0, buffer.Length);
                while (size > 0)
                {
                    zips.Write(buffer, 0, size);
                    size = StreamToZip.Read(buffer, 0, buffer.Length);
                }
            }
            catch { throw; }
            finally
            {
                if (StreamToZip != null)
                {
                    StreamToZip.Close();
                    StreamToZip.Dispose();
                }
            }
        }
        private void AddFolder(string orignalDir, string folder, ZipOutputStream zips)
        {
            //文件夹
            folder = folder.TrimEnd('/','\');
            string fileName = Path.GetFileName(folder);
            if (!string.IsNullOrEmpty(orignalDir))
            {
                fileName = orignalDir + Path.DirectorySeparatorChar + fileName ;
            }
            fileName += Path.DirectorySeparatorChar;
            ZipEntry z = new ZipEntry(fileName);
            zips.PutNextEntry(z);
        }
        /// <summary>
        /// 递归压缩文件夹内所有文件和子文件夹
        /// </summary>
        /// <param name="orignalDir">外层文件夹</param>
        /// <param name="dir">被压缩文件夹</param>
        /// <param name="zips">流</param>
        private void CompressFolder(string orignalDir,string dir, ZipOutputStream zips)
        {
            // 压缩当前文件夹下所有文件
            string[] names = Directory.GetFiles(dir);
            foreach (string fileName in names)
            {
                AddFile(orignalDir,fileName, zips);
            }
            // 压缩子文件夹
            names = Directory.GetDirectories(dir);
            foreach (string folderName in names)
            {
                AddFolder(orignalDir, folderName, zips);
    
                string _orignalDir = Path.GetFileName(folderName);
                if (!string.IsNullOrEmpty(orignalDir))
                {
                    _orignalDir = orignalDir + Path.DirectorySeparatorChar + _orignalDir;
                }
                CompressFolder(_orignalDir, folderName, zips);
            }
        }
        #endregion private
    
        #endregion 压缩文件
    
        #region 解压文件
    
        /// <inheritdoc/>
        public string UnZipFile(string zipFilePath, string unZipDir = null,string password = null)
        {
            if (!File.Exists(zipFilePath))
            {
                throw new Exception($"压缩文件【{zipFilePath}】不存在!");
            }
            //解压文件夹为空时默认与压缩文件同一级目录下,跟压缩文件同名的文件夹   
            if (string.IsNullOrWhiteSpace(unZipDir))
            {
                unZipDir = Path.GetDirectoryName(zipFilePath);
                string name = Path.GetFileNameWithoutExtension(zipFilePath);
                unZipDir = Path.Combine(unZipDir, name);
            }
    
            string unZipDir2 = unZipDir;
            char lastChar = unZipDir[unZipDir.Length - 1];
            if (lastChar != '/' && lastChar != '\')
            {
                unZipDir += Path.DirectorySeparatorChar;
            }
    
            if (!Directory.Exists(unZipDir))
                Directory.CreateDirectory(unZipDir);
    
            //解压
            UnZipProcess(zipFilePath, unZipDir, password);
    
            return unZipDir2;
        }
        private void UnZipProcess(string zipFilePath, string unZipDir, string password)
        {
            ZipInputStream zipInput = null;
            FileStream fileStream = null;
            try
            {
                fileStream = File.OpenRead(zipFilePath);
                zipInput = new ZipInputStream(fileStream);
                zipInput.Password = password;
                ZipEntry theEntry;
                while ((theEntry = zipInput.GetNextEntry()) != null)
                {
                    string tempPath = unZipDir + theEntry.Name;
                    if (theEntry.IsDirectory)
                    {
                        if (!Directory.Exists(tempPath))
                        {
                            Directory.CreateDirectory(tempPath);
                        }
                    }
                    else
                    {
                        using (FileStream streamWriter = File.Create(tempPath))
                        {
                            byte[] buffer = new byte[10240];
                            int size = zipInput.Read(buffer, 0, buffer.Length);
                            while (size > 0)
                            {
                                streamWriter.Write(buffer, 0, size);
                                size = zipInput.Read(buffer, 0, buffer.Length);
                            }
                        }
                    }
                }
            }
            catch
            {
                throw;
            }
            finally
            {
                if (fileStream != null)
                {
                    fileStream.Close();
                    fileStream.Dispose();
                }
                if (zipInput != null)
                {
                    zipInput.Close();
                    zipInput.Dispose();
                }
            }
        }
          
        #endregion
    }
  • 相关阅读:
    jquery 学习笔记
    session
    六、线程中断机制
    二、CompletableFuture(一)基础概念
    四、常见的锁
    五、synchronized细节
    三、CompletableFuture(二)常见用法
    七、等待唤醒的三种方式
    序列化 和 反序列化
    Trigger
  • 原文地址:https://www.cnblogs.com/wj033/p/6171354.html
Copyright © 2011-2022 走看看