zoukankan      html  css  js  c++  java
  • C#执行zip文件压缩的几种方法及我遇到的坑总结

    工作项目中需要用到zip压缩解压缩文件,一开始看上了Ionic.Zip.dll这个类库,操作方便,写法简单

    对应有个ziphelper类

     1 using Ionic.Zip;
     2 
     3     public static class ZipHelper
     4     {
     5 
     6         public static void UnZip(string zipPath, string outPath)
     7         {
     8             try
     9             {
    10                 using (ZipFile zip = ZipFile.Read(zipPath))
    11                 {
    12                     foreach (ZipEntry entry in zip)
    13                     {
    14                         entry.Extract(outPath, ExtractExistingFileAction.OverwriteSilently);
    15                     }
    16                 }
    17             }
    18             catch(Exception ex)
    19             {
    20                 File.WriteAllText(System.Web.HttpContext.Current.Server.MapPath("/1.txt"),ex.Message + "
    " + ex.StackTrace);
    21             }
    22         }
    23         /// <summary>
    24         /// 递归子目录时调用
    25         /// ZipHelper.Zip(files, path + model.CName + "/" + siteid + ".zip", path + model.CName + "/");
    26        /// ZipHelper.ZipDir( path + model.CName + "/" + siteid + ".zip", path + model.CName + "/", path + model.CName + "/");
    27         /// </summary>
    28         /// <param name="savefileName">要保存的文件名</param>
    29         /// <param name="childPath">要遍历的目录</param>
    30         /// <param name="startPath">压缩包起始目录结尾必须反斜杠</param>
    31 
    32         public static void ZipDir(string savefileName, string childPath, string startPath)
    33         {
    34             DirectoryInfo di = new DirectoryInfo(childPath);
    35             if (di.GetDirectories().Length > 0) //有子目录
    36             {
    37                 foreach (DirectoryInfo dirs in di.GetDirectories())
    38                 {
    39                     string[] n = Directory.GetFiles(dirs.FullName, "*");
    40                     Zip(n, savefileName, startPath);
    41                     ZipDir(savefileName, dirs.FullName, startPath);
    42                 }
    43             }
    44         }
    45         /// <summary>
    46         /// 压缩zip
    47         /// </summary>
    48         /// <param name="fileToZips">文件路径集合</param>
    49         /// <param name="zipedFile">想要压成zip的文件名</param>
    50         /// <param name="fileDirStart">文件夹起始目录结尾必须反斜杠</param>
    51         public static void Zip(string[] fileToZips, string zipedFile,string fileDirStart)
    52         {
    53             using (ZipFile zip = new ZipFile(zipedFile, Encoding.UTF8))
    54             {
    55                 foreach (string fileToZip in fileToZips)
    56                 { 
    57                     string fileName = fileToZip.Substring(fileToZip.LastIndexOf("\", StringComparison.Ordinal) + 1);
    58                     zip.AddFile(fileToZip, fileToZip.Replace(fileDirStart, "").Replace(fileName, ""));
    59                     //zip.AddFile(fileToZip, fileToZip.Replace(fileDirStart, "").Replace(fileName, ""));
    60                     //using (var fs = new FileStream(fileToZip, FileMode.Open, FileAccess.ReadWrite))
    61                     //{
    62                     //    var buffer = new byte[fs.Length];
    63                     //    fs.Read(buffer, 0, buffer.Length);
    64                     //    string fileName = fileToZip.Substring(fileToZip.LastIndexOf("\", StringComparison.Ordinal) + 1);
    65                     //    zip.AddEntry(fileName, buffer);
    66                     //}
    67                 }
    68                 zip.Save();
    69             }
    70         }
    71 
    72         public static void ZipOneFile(string from, string zipedFile, string to)
    73         {
    74             using (ZipFile zip = new ZipFile(zipedFile, Encoding.UTF8))
    75             {
    76                 zip.AddFile(from, to);
    77                 zip.Save();
    78             }
    79         }
    80 
    81     }

    使用方法:

        string path = Request.MapPath("/");
        string[] files = Directory.GetFiles(path, "*");
        ZipHelper.Zip(files, path + "1.zip", path);//压缩path下的所有文件
        ZipHelper.ZipDir(path + "1.zip", path, path);//递归压缩path下的文件夹里的文件
        ZipHelper.UnZip(Server.MapPath("/") + "lgs.zip", Server.MapPath("/"));//解压缩

    正常情况下这个使用是不会有问题的,我一直在用,不过我遇到了一个变态问题,服务器端为了安全需求,禁用了File.Move方法,然后这个类库解压缩时采用了重命名方案,然后很尴尬的执行失败,困扰了我大半年时间,一直不知道原因,不过因为这个bug时隐时现,在 个别服务器上出现,所以一直没有解决,总算最近发现问题了。

    于是我想干脆不用zip压缩了,直接调用服务器上的WinRar,这个问题显而易见,服务器如果没有安装,或者不给权限同样无法使用,我就遇到了,不过给个操作方法代码

      1 public class WinRarHelper
      2 {
      3     public WinRarHelper()
      4     {
      5 
      6     }
      7 
      8     static WinRarHelper()
      9     {
     10         //判断是否安装了WinRar.exe
     11         RegistryKey key = Registry.LocalMachine.OpenSubKey(@"SOFTWAREMicrosoftWindowsCurrentVersionApp PathsWinRAR.exe");
     12         _existSetupWinRar = !string.IsNullOrEmpty(key.GetValue(string.Empty).ToString());
     13 
     14         //获取WinRar.exe路径
     15         _winRarPath = key.GetValue(string.Empty).ToString();
     16     }
     17 
     18     static bool _existSetupWinRar;
     19     /// <summary>
     20     /// 获取是否安装了WinRar的标识
     21     /// </summary>
     22     public static bool ExistSetupWinRar
     23     {
     24         get { return _existSetupWinRar; }
     25     }
     26 
     27     static string _winRarPath;
     28     /// <summary>
     29     /// 获取WinRar.exe路径
     30     /// </summary>
     31     public static string WinRarPath
     32     {
     33         get { return _winRarPath; }
     34     }
     35 
     36     #region 压缩到.rar,这个方法针对目录压缩
     37     /// <summary>
     38     /// 压缩到.rar,这个方法针对目录压缩
     39     /// </summary>
     40     /// <param name="intputPath">输入目录</param>
     41     /// <param name="outputPath">输出目录</param>
     42     /// <param name="outputFileName">输出文件名</param>
     43     public static void CompressRar(string intputPath, string outputPath, string outputFileName)
     44     {
     45         //rar 执行时的命令、参数
     46         string rarCmd;
     47         //启动进程的参数
     48         ProcessStartInfo processStartInfo = new ProcessStartInfo();
     49         //进程对象
     50         Process process = new Process();
     51         try
     52         {
     53             if (!ExistSetupWinRar)
     54             {
     55                 throw new ArgumentException("请确认服务器上已安装WinRar应用!");
     56             }
     57             //判断输入目录是否存在
     58             if (!Directory.Exists(intputPath))
     59             {
     60                 throw new ArgumentException("指定的要压缩目录不存在!");
     61             }
     62             //命令参数  uxinxin修正参数压缩文件到当前目录,而不是从盘符开始
     63             rarCmd = " a " + outputFileName + " " + "./" + " -r";
     64             //rarCmd = " a " + outputFileName + " " + outputPath + " -r";
     65             //创建启动进程的参数
     66             //指定启动文件名
     67             processStartInfo.FileName = WinRarPath;
     68             //指定启动该文件时的命令、参数
     69             processStartInfo.Arguments = rarCmd;
     70             //指定启动窗口模式:隐藏
     71             processStartInfo.WindowStyle = ProcessWindowStyle.Hidden;
     72             //指定压缩后到达路径
     73             processStartInfo.WorkingDirectory = outputPath;
     74             //创建进程对象
     75             
     76             //指定进程对象启动信息对象
     77             process.StartInfo = processStartInfo;
     78             //启动进程
     79             process.Start();
     80             //指定进程自行退行为止
     81             process.WaitForExit();
     82             //Uxinxin增加的清理关闭,不知道是否有效
     83             process.Close();
     84             process.Dispose();
     85         }
     86         catch (Exception ex)
     87         {
     88             throw ex;
     89         }
     90         finally
     91         {
     92             process.Close();
     93             process.Dispose();
     94 
     95         }
     96     }
     97     #endregion
     98 
     99     #region 解压.rar
    100     /// <summary>
    101     /// 解压.rar
    102     /// </summary>
    103     /// <param name="inputRarFileName">输入.rar</param>
    104     /// <param name="outputPath">输出目录</param>
    105     public static void UnCompressRar(string inputRarFileName, string outputPath)
    106     {
    107         //rar 执行时的命令、参数
    108         string rarCmd;
    109         //启动进程的参数
    110         ProcessStartInfo processStartInfo = new ProcessStartInfo();
    111         //进程对象
    112         Process process = new Process();
    113         try
    114         {
    115             if (!ExistSetupWinRar)
    116             {
    117                 throw new ArgumentException("请确认服务器上已安装WinRar应用!");
    118             }
    119             //如果压缩到目标路径不存在
    120             if (!Directory.Exists(outputPath))
    121             {
    122                 //创建压缩到目标路径
    123                 Directory.CreateDirectory(outputPath);
    124             }
    125             rarCmd = "x " + inputRarFileName + " " + outputPath + " -y";
    126 
    127 
    128             processStartInfo.FileName = WinRarPath;
    129             processStartInfo.Arguments = rarCmd;
    130             processStartInfo.WindowStyle = ProcessWindowStyle.Hidden;
    131             processStartInfo.WorkingDirectory = outputPath;
    132 
    133 
    134             process.StartInfo = processStartInfo;
    135             process.Start();
    136             process.WaitForExit();
    137             process.Close();
    138             process.Dispose();
    139         }
    140         catch (Exception ex)
    141         {
    142             throw ex;
    143         }
    144         finally
    145         {
    146             process.Close();
    147             process.Dispose();
    148         }
    149     }
    150     #endregion
    151 
    152     #region 将传入的文件列表压缩到指定的目录下
    153     /// <summary>
    154     /// 将传入的文件列表压缩到指定的目录下
    155     /// </summary>
    156     /// <param name="sourceFilesPaths">要压缩的文件路径列表</param>
    157     /// <param name="compressFileSavePath">压缩文件存放路径</param>
    158     /// <param name="compressFileName">压缩文件名(全名)</param>
    159     public static void CompressFilesToRar(List<string> sourceFilesPaths, string compressFileSavePath, string compressFileName)
    160     {
    161         //rar 执行时的命令、参数
    162         string rarCmd;
    163         //启动进程的参数
    164         ProcessStartInfo processStartInfo = new ProcessStartInfo();
    165         //创建进程对象
    166         //进程对象
    167         Process process = new Process();
    168         try
    169         {
    170             if (!ExistSetupWinRar)
    171             {
    172                 throw new ArgumentException("Not setuping the winRar, you can Compress.make sure setuped winRar.");
    173             }
    174             //判断输入文件列表是否为空
    175             if (sourceFilesPaths == null || sourceFilesPaths.Count < 1)
    176             {
    177                 throw new ArgumentException("CompressRar'arge : sourceFilesPaths cannot be null.");
    178             }
    179             rarCmd = " a -ep1 -ap " + compressFileName;
    180                 //-ep1 -ap表示压缩时不保留原有文件的路径,都压缩到压缩包中即可,调用winrar命令内容可以参考我转载的另一篇文章:教你如何在DOS(cmd)下使用WinRAR压缩文件
    181             foreach (object filePath in sourceFilesPaths)
    182             {
    183                 rarCmd += " " + filePath.ToString(); //每个文件路径要与其他的文件用空格隔开
    184             }
    185             //rarCmd += " -r";
    186             //创建启动进程的参数
    187 
    188             //指定启动文件名
    189             processStartInfo.FileName = WinRarPath;
    190             //指定启动该文件时的命令、参数
    191             processStartInfo.Arguments = rarCmd;
    192             //指定启动窗口模式:隐藏
    193             processStartInfo.WindowStyle = ProcessWindowStyle.Hidden;
    194             //指定压缩后到达路径
    195             processStartInfo.WorkingDirectory = compressFileSavePath;
    196 
    197             //指定进程对象启动信息对象
    198             process.StartInfo = processStartInfo;
    199             //启动进程
    200             process.Start();
    201             //指定进程自行退行为止
    202             process.WaitForExit();
    203             process.Close();
    204             process.Dispose();
    205         }
    206         catch (Exception ex)
    207         {
    208             throw ex;
    209         }
    210         finally
    211         {
    212             process.Close();
    213             process.Dispose();
    214         }
    215     }
    216     #endregion
    217 }

    调用方法:

    if (WinRarHelper.ExistSetupWinRar)
            {
                try
                {
                    WinRarHelper.CompressRar(Server.MapPath("/"), Server.MapPath("/"), "1.zip");
                    Response.Write("压缩完成!" + DateTime.Now);
                }
                catch (Win32Exception e1)
                {
                    Response.Write(e1.Message + "<br>" + "服务器端禁止是我们网站使用WinRar应用执行!<br>");
                }
                catch (Exception e1)
                {
                    Response.Write(e1.Message + "<br>" + e1.StackTrace);
                }

            if (WinRarHelper.ExistSetupWinRar)
            {
                try
                {
                    WinRarHelper.UnCompressRar(Server.MapPath("/") + "lgs.zip", Server.MapPath("/"));
                    Response.Write("解压缩完成!" + DateTime.Now);
                }
                catch (Win32Exception e1)
                {
                    Response.Write(e1.Message + "<br>" + "服务器端禁止是我们网站使用WinRar应用执行!<br>");

                }
                catch (Exception e1)
                {
                    Response.Write(e1.Message);
                }
            }

    最后我找到了一个解压的时候不用重命名方法的,还好服务器对解压没限制

    ICSharpCode.SharpZipLib.dll  用到这个文件

    参考来自http://www.cnblogs.com/yuangang/p/5581391.html

    具体我也不写了,就看参考网站吧,我也没改代码,不错,记录一下,花了我整整一天折腾这玩意儿!

  • 相关阅读:
    C语言宏中"#"和"##"的用法
    Ubuntu 14.04 LTS 安装和配置Bochs
    C和C++中static的比较
    总线设备驱动模型
    驱动设计的思想:面向对象/分层/分离
    基于分层思想的驱动程序软件框架
    单元测试指南
    Apollo移植
    剑指offer python版 数组中出现次数超过一半的数字
    剑指offer python版 字符串的排列
  • 原文地址:https://www.cnblogs.com/uxinxin/p/6268195.html
Copyright © 2011-2022 走看看