【转】C#执行rar,zip文件压缩的几种方法及我遇到的坑总结

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

对应有个ziphelper类

 

using Ionic.Zip;public static class ZipHelper{public static void UnZip(string zipPath, string outPath){try{using (ZipFile zip = ZipFile.Read(zipPath)){foreach (ZipEntry entry in zip){entry.Extract(outPath, ExtractExistingFileAction.OverwriteSilently);}}}catch(Exception ex){File.WriteAllText(System.Web.HttpContext.Current.Server.MapPath("/1.txt"),ex.Message + "\r\n" + ex.StackTrace);}}/// <summary>/// 递归子目录时调用/// ZipHelper.Zip(files, path + model.CName + "/" + siteid + ".zip", path + model.CName + "/");/// ZipHelper.ZipDir( path + model.CName + "/" + siteid + ".zip", path + model.CName + "/", path + model.CName + "/");/// </summary>/// <param name="savefileName">要保存的文件名</param>/// <param name="childPath">要遍历的目录</param>/// <param name="startPath">压缩包起始目录结尾必须反斜杠</param>public static void ZipDir(string savefileName, string childPath, string startPath){DirectoryInfo di = new DirectoryInfo(childPath);if (di.GetDirectories().Length > 0) //有子目录{foreach (DirectoryInfo dirs in di.GetDirectories()){string[] n = Directory.GetFiles(dirs.FullName, "*");Zip(n, savefileName, startPath);ZipDir(savefileName, dirs.FullName, startPath);}}}/// <summary>/// 压缩zip/// </summary>/// <param name="fileToZips">文件路径集合</param>/// <param name="zipedFile">想要压成zip的文件名</param>/// <param name="fileDirStart">文件夹起始目录结尾必须反斜杠</param>public static void Zip(string[] fileToZips, string zipedFile,string fileDirStart){using (ZipFile zip = new ZipFile(zipedFile, Encoding.UTF8)){foreach (string fileToZip in fileToZips){ string fileName = fileToZip.Substring(fileToZip.LastIndexOf("\\", StringComparison.Ordinal) + 1);zip.AddFile(fileToZip, fileToZip.Replace(fileDirStart, "").Replace(fileName, ""));//zip.AddFile(fileToZip, fileToZip.Replace(fileDirStart, "").Replace(fileName, ""));//using (var fs = new FileStream(fileToZip, FileMode.Open, FileAccess.ReadWrite))//{//    var buffer = new byte[fs.Length];//    fs.Read(buffer, 0, buffer.Length);//    string fileName = fileToZip.Substring(fileToZip.LastIndexOf("\\", StringComparison.Ordinal) + 1);//    zip.AddEntry(fileName, buffer);//}}zip.Save();}}public static void ZipOneFile(string from, string zipedFile, string to){using (ZipFile zip = new ZipFile(zipedFile, Encoding.UTF8)){zip.AddFile(from, to);zip.Save();}}}

使用方法:

    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,这个问题显而易见,服务器如果没有安装,或者不给权限同样无法使用,我就遇到了,不过给个操作方法代码

public class WinRarHelper
{public WinRarHelper(){}static WinRarHelper(){//判断是否安装了WinRar.exeRegistryKey key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\WinRAR.exe");_existSetupWinRar = !string.IsNullOrEmpty(key.GetValue(string.Empty).ToString());//获取WinRar.exe路径_winRarPath = key.GetValue(string.Empty).ToString();}static bool _existSetupWinRar;/// <summary>/// 获取是否安装了WinRar的标识/// </summary>public static bool ExistSetupWinRar{get { return _existSetupWinRar; }}static string _winRarPath;/// <summary>/// 获取WinRar.exe路径/// </summary>public static string WinRarPath{get { return _winRarPath; }}#region 压缩到.rar,这个方法针对目录压缩/// <summary>/// 压缩到.rar,这个方法针对目录压缩/// </summary>/// <param name="intputPath">输入目录</param>/// <param name="outputPath">输出目录</param>/// <param name="outputFileName">输出文件名</param>public static void CompressRar(string intputPath, string outputPath, string outputFileName){//rar 执行时的命令、参数string rarCmd;//启动进程的参数ProcessStartInfo processStartInfo = new ProcessStartInfo();//进程对象Process process = new Process();try{if (!ExistSetupWinRar){throw new ArgumentException("请确认服务器上已安装WinRar应用!");}//判断输入目录是否存在if (!Directory.Exists(intputPath)){throw new ArgumentException("指定的要压缩目录不存在!");}//命令参数  uxinxin修正参数压缩文件到当前目录,而不是从盘符开始rarCmd = " a " + outputFileName + " " + "./" + " -r";//rarCmd = " a " + outputFileName + " " + outputPath + " -r";//创建启动进程的参数//指定启动文件名processStartInfo.FileName = WinRarPath;//指定启动该文件时的命令、参数processStartInfo.Arguments = rarCmd;//指定启动窗口模式:隐藏processStartInfo.WindowStyle = ProcessWindowStyle.Hidden;//指定压缩后到达路径processStartInfo.WorkingDirectory = outputPath;//创建进程对象//指定进程对象启动信息对象process.StartInfo = processStartInfo;//启动进程process.Start();//指定进程自行退行为止process.WaitForExit();//Uxinxin增加的清理关闭,不知道是否有效process.Close();process.Dispose();}catch (Exception ex){throw ex;}finally{process.Close();process.Dispose();}}#endregion#region 解压.rar/// <summary>/// 解压.rar/// </summary>/// <param name="inputRarFileName">输入.rar</param>/// <param name="outputPath">输出目录</param>public static void UnCompressRar(string inputRarFileName, string outputPath){//rar 执行时的命令、参数string rarCmd;//启动进程的参数ProcessStartInfo processStartInfo = new ProcessStartInfo();//进程对象Process process = new Process();try{if (!ExistSetupWinRar){throw new ArgumentException("请确认服务器上已安装WinRar应用!");}//如果压缩到目标路径不存在if (!Directory.Exists(outputPath)){//创建压缩到目标路径Directory.CreateDirectory(outputPath);}rarCmd = "x " + inputRarFileName + " " + outputPath + " -y";processStartInfo.FileName = WinRarPath;processStartInfo.Arguments = rarCmd;processStartInfo.WindowStyle = ProcessWindowStyle.Hidden;processStartInfo.WorkingDirectory = outputPath;process.StartInfo = processStartInfo;process.Start();process.WaitForExit();process.Close();process.Dispose();}catch (Exception ex){throw ex;}finally{process.Close();process.Dispose();}}#endregion#region 将传入的文件列表压缩到指定的目录下/// <summary>/// 将传入的文件列表压缩到指定的目录下/// </summary>/// <param name="sourceFilesPaths">要压缩的文件路径列表</param>/// <param name="compressFileSavePath">压缩文件存放路径</param>/// <param name="compressFileName">压缩文件名(全名)</param>public static void CompressFilesToRar(List<string> sourceFilesPaths, string compressFileSavePath, string compressFileName){//rar 执行时的命令、参数string rarCmd;//启动进程的参数ProcessStartInfo processStartInfo = new ProcessStartInfo();//创建进程对象//进程对象Process process = new Process();try{if (!ExistSetupWinRar){throw new ArgumentException("Not setuping the winRar, you can Compress.make sure setuped winRar.");}//判断输入文件列表是否为空if (sourceFilesPaths == null || sourceFilesPaths.Count < 1){throw new ArgumentException("CompressRar'arge : sourceFilesPaths cannot be null.");}rarCmd = " a -ep1 -ap " + compressFileName;//-ep1 -ap表示压缩时不保留原有文件的路径,都压缩到压缩包中即可,调用winrar命令内容可以参考我转载的另一篇文章:教你如何在DOS(cmd)下使用WinRAR压缩文件foreach (object filePath in sourceFilesPaths){rarCmd += " " + filePath.ToString(); //每个文件路径要与其他的文件用空格隔开}//rarCmd += " -r";//创建启动进程的参数//指定启动文件名processStartInfo.FileName = WinRarPath;//指定启动该文件时的命令、参数processStartInfo.Arguments = rarCmd;//指定启动窗口模式:隐藏processStartInfo.WindowStyle = ProcessWindowStyle.Hidden;//指定压缩后到达路径processStartInfo.WorkingDirectory = compressFileSavePath;//指定进程对象启动信息对象process.StartInfo = processStartInfo;//启动进程process.Start();//指定进程自行退行为止process.WaitForExit();process.Close();process.Dispose();}catch (Exception ex){throw ex;}finally{process.Close();process.Dispose();}}#endregion
}

调用方法:

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/439229.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【LeetCode - 42. 接雨水】

42. 接雨水 难度困难3164 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图&#xff0c;计算按此排列的柱子&#xff0c;下雨之后能接多少雨水。 示例 1&#xff1a; 输入&#xff1a;height [0,1,0,2,1,0,1,3,2,1,2,1] 输出&#xff1a;6 解释&#xff1a;上面是由数组 […

【转】C#打包文件夹成zip格式(包括文件夹和子文件夹下的所有文件)

C#打包zip文件可以调用现成的第三方dll&#xff0c;事半功倍&#xff0c;而且该dll完全免费&#xff0c;下载地址&#xff1a;SharpZipLib 下载完解压缩后&#xff0c;把 ICSharpCode.SharpZipLib.dll 拷贝到当前项目的目录下&#xff08;如果偷懒的话&#xff0c;可以直接拷贝…

【LeetCode】第283场周赛题解

本场题题目不难&#xff0c;但是力求写出精简优雅的代码&#xff0c;还是有需要学习的地方的。 第一题 力扣 class Solution:def cellsInRange(self, s: str) -> List[str]:ans []a,b,c,d s[0],s[1],s[3],s[4]for i in range(ord(a), ord(c)1):for j in range(int(b),int…

Linq to Sql : 三种事务处理方式

Linq to SQL支持三种事务处理模型&#xff1a;显式本地事务、显式可分发事务、隐式事务。(from MSDN: 事务 (LINQ to SQL))。MSDN中描述得相对比较粗狂&#xff0c;下面就结合实例来对此进行阐述。 0. 测试环境 OSWindows Server 2008 Enterprise sp1IDEVisual Studio 2008, …

【LeetCode - 33】搜索旋转排序数组(二分)

力扣 解题报告&#xff1a; 二分。但是有不少细节要考虑清楚。 所以干脆考虑另一种二分的方式。也就是第二次二分的时候&#xff0c;把两半数组给拼成一个完整的数组&#xff0c;当然下标需要是虚拟的&#xff0c;这一步可以用偏移量取模完成。这样就不需要考虑边界情况了。 …

SHAREPOINT - CAML列表查询

首先要了解的是CAML(Collaboration Application Markup Language)不仅仅是用在对列表、文档库的查询&#xff0c;字段的定义&#xff0c;站点定义等处处使用的都是CAML。 简单的提一下CAML列表查询相关知识&#xff0c;请注意CAML查询无论对于标签还是值均大小写敏感 CAML查询…

【LeetCode - 1765】. 地图中的最高点

力扣 解题报告&#xff1a; 多元BFS。 进阶一下&#xff1a; 二维数组&#xff0c;1表示等高线&#xff0c;0表示平地&#xff0c;比如 输入 010 111 010 输出 010 121 010输入 010 101 010 输出 010 111 010即输入一个二维地图&#xff0c;保证等高线一定是闭合的环&#x…

Linq找不到行或行已更改

1.debug确认&#xff0c;待修改记录已经正确定位&#xff0c;各字段均已正确赋值 2.最后发现原来是Linq使用的表实际中有个字段&#xff0c;数据库中为Nullable&#xff0c;而dbml是Not Nullable&#xff0c;二者不一致 一个逻辑是&#xff0c;我现在填写的是非空值&#xff…

【LeetCode - 32】最长有效括号

给你一个只包含 ( 和 ) 的字符串&#xff0c;找出最长有效&#xff08;格式正确且连续&#xff09;括号子串的长度。 示例 1&#xff1a; 输入&#xff1a;s "(()" 输出&#xff1a;2 解释&#xff1a;最长有效括号子串是 "()" 示例 2&#xff1a; 输入…

【转】微服务架构下分布式事务方案

1 微服务的发展 微服务倡导将复杂的单体应用拆分为若干个功能简单、松耦合的服务&#xff0c;这样可以降低开发难度、增强扩展性、便于敏捷开发。当前被越来越多的开发者推崇&#xff0c;很多互联网行业巨头、开源社区等都开始了微服务的讨论和实践。Hailo有160个不同服务构成…

【LeetCode - 443】压缩字符串(模拟)

解题报告&#xff1a; 直接模拟。 class Solution { public:int compress(vector<char>& chars) {int p 0;for(int i 0; i<chars.size();) {int j i1;while(j<chars.size() && chars[j] chars[i]) j;chars[p] chars[i];if(j-i > 1) {int cnt…

Linq to SQL之使用事务

事务是一个原子的工作单位&#xff0c;必须完整的完成单位里的所有工作&#xff0c;要么全部执行&#xff0c;要么全部都不执行。如果提交事务&#xff0c;则事务执行成功&#xff1b;如果回滚事务&#xff0c;则事务执行失败。 事务具备4个基本特性--ACID(原子性、一致性、孤立…

【LeetCode - 798】得分最高的最小轮调(转化法)

解题报告&#xff1a; 思路一&#xff1a;这题首先说一个nlogn的方法。 首先一个主客转化&#xff0c;题目描述是说把数组做翻转&#xff0c;idx不变&#xff0c;然后nums[i]和i作比较。那么我们可以转化为让数组不变&#xff0c;idx转变&#xff0c;即&#xff1a;假设刚开始…

【转】聊聊分布式事务,再说说解决方案

前言 最近很久没有写博客了&#xff0c;一方面是因为公司事情最近比较忙&#xff0c;另外一方面是因为在进行 CAP 的下一阶段的开发工作&#xff0c;不过目前已经告一段落了。 接下来还是开始我们今天的话题&#xff0c;说说分布式事务&#xff0c;或者说是我眼中的分布式事务…

【LeetCode - 2049】统计最高分的节点数目

解题报告&#xff1b; 直接dp。注意mx也得longlong AC代码&#xff1a; class Solution { public:vector<int> vv[200005];int sum[200005];long long ans[200005];int n;void dfs(int x) {ans[x] 1; sum[x] 1;for(int i 0; i<vv[x].size(); i) {dfs(vv[x][i]);s…

Web Service 实现分布式事务

首先要声明&#xff0c;不推荐在web service中实现分布式事务。 原因如下&#xff1a;   1、webservice在通信层上是一种无连接的协议&#xff0c;每两次调用之间&#xff0c;tcp连接是断开的。而分布式事务需要保存事务上下文&#xff0c;这是一个难点   2、web service是…

【LeetCode每日一题】2024. 考试的最大困扰度

​​​​​​力扣 解题报告&#xff1a; 因为只有T和F两个元素&#xff0c;不难证明单向性。尺取法解决。当然这题也可以二分。 AC代码&#xff1a; class Solution { public:int maxConsecutiveAnswers(string answerKey, int k) {int l 0, r 0;int T 0, F 0;int ans …

使用WebService如何实现分布式事务

在 System.EnterpriseServices 名称空间中实现了COM服务的相关类&#xff0c;其中就提供事务支持。 你可以在你的方法上加上TransactionAttribute特性标记&#xff0c;那个方法就支持事务了。 然后在那个方法中就可以用ContextUtil.SetComplete()和ContextUtil.SetAbort()方法分…

【Leetcode - 172】阶乘后的零(思维)

给定一个整数 n &#xff0c;返回 n! 结果中尾随零的数量。 提示 n! n * (n - 1) * (n - 2) * ... * 3 * 2 * 1 示例 1&#xff1a; 输入&#xff1a;n 3 输出&#xff1a;0 解释&#xff1a;3! 6 &#xff0c;不含尾随 0 示例 2&#xff1a; 输入&#xff1a;n 5 输出&…

linq、lambda、entity framework之间的关系

lambda&#xff1a; 一种匿名委托的精简版写法&#xff0c;明显的标志是>符号 entity framework&#xff08;简称EF&#xff09;&#xff1a; 微软访问数据库的最快捷最成熟的框架&#xff08;ORM&#xff09;&#xff0c;在EF出现以前有SqlHelper、NHibernate等访问数据库…