C#执行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 > ) //有子目录
{
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) + );
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.exe
RegistryKey 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 < )
{
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
具体我也不写了,就看参考网站吧,我也没改代码,不错,记录一下,花了我整整一天折腾这玩意儿!
C#执行zip文件压缩的几种方法及我遇到的坑总结的更多相关文章
- Linux下查看压缩文件内容的 10 种方法
Linux下查看压缩文件内容的 10 种方法 通常来说,我们查看归档或压缩文件的内容,需要先进行解压缩,然后再查看,比较麻烦.今天给大家介绍 10 不同方法,能够让你轻松地在未解压缩的情况下查看归档或 ...
- 总结删除文件或文件夹的7种方法-JAVA IO基础总结第4篇
本文是Java IO总结系列篇的第4篇,前篇的访问地址如下: 总结java中创建并写文件的5种方式-JAVA IO基础总结第一篇 总结java从文件中读取数据的6种方法-JAVA IO基础总结第二篇 ...
- linux中快速清空文件内容的几种方法
这篇文章主要介绍了linux中快速清空文件内容的几种方法,需要的朋友可以参考下 $ : > filename $ > filename $ echo "" > f ...
- Linux清除文件内容的几种方法
# 清空或删除大文件内容的五种方法: # 法一:通过重定向到 Null 来清空文件内容 $ >test.sh # 法二:使用 ‘true' 命令重定向来清空文件 $ true > test ...
- linux清空文件内容的三种方法
linux系统中清空文件内容的三种方法 1.使用vi/vim命令打开文件后,输入"%d"清空,后保存即可.但当文件内容较大时,处理较慢,命令如下:vim file_name:%d: ...
- php获取文件后缀的9种方法
获取文件后缀的9种方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 3 ...
- 在Linux文件清空的几种方法
在Linux文件清空的几种方法 1.使用重定向的方法 [root@centos7 ~]# du -h test.txt 4.0K test.txt [root@centos7 ~]# > tes ...
- 【转】Linux 中清空或删除大文件内容的五种方法(truncate 命令清空文件)
原文: http://www.jb51.net/article/100462.htm truncate -s 0 access.log -------------------------------- ...
- php中读取文件内容的几种方法。(file_get_contents:将文件内容读入一个字符串)
php中读取文件内容的几种方法.(file_get_contents:将文件内容读入一个字符串) 一.总结 php中读取文件内容的几种方法(file_get_contents:将文件内容读入一个字符串 ...
随机推荐
- Android应用程序绑定服务(bindService)的过程源代码分析
文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6745181 Android应用程序组件Serv ...
- ORACLE数据库常用查询二
ORACLE数据库常用查询 1.查看表空间对应数据文件情况: SQL MB,AUTOEXTENSIBLE FROM DBA_DATA_FILES; TABLESPACE_NAME FILE_NAME ...
- 配置元素customErrors
Asp.net配置文件的配置方式,其实在MSDN里面是写得最清楚的了.可惜之前一直未曾了解到MSDN的强大. 先贴个地址:http://msdn.microsoft.com/zh-cn/library ...
- c#中传递参数前加out
首先:两者都是按地址传递的,使用后都将改变原来参数的数值. 其次: rel 可以把参数的数值传递进函数,但是 out 是要把参数清空,就是说你无法把一个数值 从 out 传递进去的, out 进去后, ...
- NOT 运算符
NOT运算符不是独立的,它是一个可以放在任何逻辑表达式前面的修饰符,能得到与结果相反的结果.所以,如果一个表达式是真,就会得到假:如果是假,就会得到真.有时测试查找条件的反面更容易.不过,NOT运算符 ...
- NSBundle 类
NSBundle NSBundle继承于NSObject,NSBundle是一个程序包,其中包含了程序会使用的资源(图像,声音,编辑好的代码,nib文件). 一. 初始化NSBundle + (ins ...
- HTML5简单入门系列(六)
前言 之前几篇已经将HTML5的主要新增元素和特性简单介绍完毕,LZ一直在犹豫还要不要把其他元素也写出来,因为其实没什么东西可以写,就是自己用到时看一下就行.不过为了入门系列的完整,犹豫再三,还是决定 ...
- [C++程序设计]基于对象的程序设计 基于对象的程序设计
1. 面向对象分析(object oriented analysis,OOA)2. 面向对象设计(object oriented design,OOD)3. 面向对象编程(object oriente ...
- H.数7(模拟)
1212: H.数7 时间限制: 1 Sec 内存限制: 64 MB 提交: 8 解决: 5 标签提交统计讨论版 题目描述 数7是一个简单的饭桌游戏,有很多人围成一桌,先从任意一人开始数数,1.2 ...
- 跪求 EF缓存问题 也不知道是不是缓存 问题
1.数据库里面查的结果 2 vs里面查的结果 为什么 不是16 而是2 下面是代码 /// <summary> /// 权限检查 /// </summary> public ...