【转】C#执行rar,zip文件压缩的几种方法及我遇到的坑总结
工作項(xiàng)目中需要用到zip壓縮解壓縮文件,一開(kāi)始看上了Ionic.Zip.dll這個(gè)類庫(kù),操作方便,寫法簡(jiǎn)單
對(duì)應(yīng)有個(gè)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>/// 遞歸子目錄時(shí)調(diào)用/// 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">壓縮包起始目錄結(jié)尾必須反斜杠</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">文件夾起始目錄結(jié)尾必須反斜杠</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("/"));//解壓縮
正常情況下這個(gè)使用是不會(huì)有問(wèn)題的,我一直在用,不過(guò)我遇到了一個(gè)變態(tài)問(wèn)題,服務(wù)器端為了安全需求,禁用了File.Move方法,然后這個(gè)類庫(kù)解壓縮時(shí)采用了重命名方案,然后很尷尬的執(zhí)行失敗,困擾了我大半年時(shí)間,一直不知道原因,不過(guò)因?yàn)檫@個(gè)bug時(shí)隱時(shí)現(xiàn),在 個(gè)別服務(wù)器上出現(xiàn),所以一直沒(méi)有解決,總算最近發(fā)現(xiàn)問(wèn)題了。
于是我想干脆不用zip壓縮了,直接調(diào)用服務(wù)器上的WinRar,這個(gè)問(wèn)題顯而易見(jiàn),服務(wù)器如果沒(méi)有安裝,或者不給權(quán)限同樣無(wú)法使用,我就遇到了,不過(guò)給個(gè)操作方法代碼
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的標(biāo)識(shí)/// </summary>public static bool ExistSetupWinRar{get { return _existSetupWinRar; }}static string _winRarPath;/// <summary>/// 獲取WinRar.exe路徑/// </summary>public static string WinRarPath{get { return _winRarPath; }}#region 壓縮到.rar,這個(gè)方法針對(duì)目錄壓縮/// <summary>/// 壓縮到.rar,這個(gè)方法針對(duì)目錄壓縮/// </summary>/// <param name="intputPath">輸入目錄</param>/// <param name="outputPath">輸出目錄</param>/// <param name="outputFileName">輸出文件名</param>public static void CompressRar(string intputPath, string outputPath, string outputFileName){//rar 執(zhí)行時(shí)的命令、參數(shù)string rarCmd;//啟動(dòng)進(jìn)程的參數(shù)ProcessStartInfo processStartInfo = new ProcessStartInfo();//進(jìn)程對(duì)象Process process = new Process();try{if (!ExistSetupWinRar){throw new ArgumentException("請(qǐng)確認(rèn)服務(wù)器上已安裝WinRar應(yīng)用!");}//判斷輸入目錄是否存在if (!Directory.Exists(intputPath)){throw new ArgumentException("指定的要壓縮目錄不存在!");}//命令參數(shù) uxinxin修正參數(shù)壓縮文件到當(dāng)前目錄,而不是從盤符開(kāi)始rarCmd = " a " + outputFileName + " " + "./" + " -r";//rarCmd = " a " + outputFileName + " " + outputPath + " -r";//創(chuàng)建啟動(dòng)進(jìn)程的參數(shù)//指定啟動(dòng)文件名processStartInfo.FileName = WinRarPath;//指定啟動(dòng)該文件時(shí)的命令、參數(shù)processStartInfo.Arguments = rarCmd;//指定啟動(dòng)窗口模式:隱藏processStartInfo.WindowStyle = ProcessWindowStyle.Hidden;//指定壓縮后到達(dá)路徑processStartInfo.WorkingDirectory = outputPath;//創(chuàng)建進(jìn)程對(duì)象//指定進(jìn)程對(duì)象啟動(dòng)信息對(duì)象process.StartInfo = processStartInfo;//啟動(dòng)進(jìn)程process.Start();//指定進(jìn)程自行退行為止process.WaitForExit();//Uxinxin增加的清理關(guān)閉,不知道是否有效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 執(zhí)行時(shí)的命令、參數(shù)string rarCmd;//啟動(dòng)進(jìn)程的參數(shù)ProcessStartInfo processStartInfo = new ProcessStartInfo();//進(jìn)程對(duì)象Process process = new Process();try{if (!ExistSetupWinRar){throw new ArgumentException("請(qǐng)確認(rèn)服務(wù)器上已安裝WinRar應(yīng)用!");}//如果壓縮到目標(biāo)路徑不存在if (!Directory.Exists(outputPath)){//創(chuàng)建壓縮到目標(biāo)路徑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 執(zhí)行時(shí)的命令、參數(shù)string rarCmd;//啟動(dòng)進(jìn)程的參數(shù)ProcessStartInfo processStartInfo = new ProcessStartInfo();//創(chuàng)建進(jìn)程對(duì)象//進(jìn)程對(duì)象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表示壓縮時(shí)不保留原有文件的路徑,都?jí)嚎s到壓縮包中即可,調(diào)用winrar命令內(nèi)容可以參考我轉(zhuǎn)載的另一篇文章:教你如何在DOS(cmd)下使用WinRAR壓縮文件foreach (object filePath in sourceFilesPaths){rarCmd += " " + filePath.ToString(); //每個(gè)文件路徑要與其他的文件用空格隔開(kāi)}//rarCmd += " -r";//創(chuàng)建啟動(dòng)進(jìn)程的參數(shù)//指定啟動(dòng)文件名processStartInfo.FileName = WinRarPath;//指定啟動(dòng)該文件時(shí)的命令、參數(shù)processStartInfo.Arguments = rarCmd;//指定啟動(dòng)窗口模式:隱藏processStartInfo.WindowStyle = ProcessWindowStyle.Hidden;//指定壓縮后到達(dá)路徑processStartInfo.WorkingDirectory = compressFileSavePath;//指定進(jìn)程對(duì)象啟動(dòng)信息對(duì)象process.StartInfo = processStartInfo;//啟動(dòng)進(jìn)程process.Start();//指定進(jìn)程自行退行為止process.WaitForExit();process.Close();process.Dispose();}catch (Exception ex){throw ex;}finally{process.Close();process.Dispose();}}#endregion }調(diào)用方法:
if (WinRarHelper.ExistSetupWinRar)
? ? ? ? {
? ? ? ? ? ? try
? ? ? ? ? ? {
? ? ? ? ? ? ? ? WinRarHelper.CompressRar(Server.MapPath("/"), Server.MapPath("/"), "1.zip");
? ? ? ? ? ? ? ? Response.Write("壓縮完成!" + DateTime.Now);
? ? ? ? ? ? }
? ? ? ? ? ? catch (Win32Exception e1)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? Response.Write(e1.Message + "<br>" + "服務(wù)器端禁止是我們網(wǎng)站使用WinRar應(yīng)用執(zhí)行!<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>" + "服務(wù)器端禁止是我們網(wǎng)站使用WinRar應(yīng)用執(zhí)行!<br>");
? ? ? ? ? ? }
? ? ? ? ? ? catch (Exception e1)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? Response.Write(e1.Message);
? ? ? ? ? ? }
? ? ? ? }
最后我找到了一個(gè)解壓的時(shí)候不用重命名方法的,還好服務(wù)器對(duì)解壓沒(méi)限制
ICSharpCode.SharpZipLib.dll ?用到這個(gè)文件
參考來(lái)自http://www.cnblogs.com/yuangang/p/5581391.html
具體我也不寫了,就看參考網(wǎng)站吧,我也沒(méi)改代碼,不錯(cuò),記錄一下,花了我整整一天折騰這玩意兒!
總結(jié)
以上是生活随笔為你收集整理的【转】C#执行rar,zip文件压缩的几种方法及我遇到的坑总结的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 《操作系统真象还原》-阅读笔记(下)
- 下一篇: 抖音博主曝一知名车评人收雪铁龙200万黑