C#壓縮或解壓(rar和zip檔案)
為了便於檔案在網路中的傳輸和儲存,通常將檔案進行壓縮操作,常用的壓縮格式有rar、zip和7z,本文將介紹在C#中如何對這幾種型別的檔案進行壓縮和解壓,並提供一些在C#中解壓縮檔案的開源庫。
在C#.NET中壓縮解壓rar檔案
rar格式是一種具有專利檔案的壓縮格式,是一種商業壓縮格式,不開源,對解碼演算法是公開的,但壓縮演算法是私有的,需要付費,如果需要在您的商業軟體中使用rar格式進行解壓縮,那麼你需要為rar付費,rar在國內很流行是由於盜版的存在,正因為演算法是不開源的,所以我們壓縮rar並沒有第三方的開源庫可供選擇,只能另尋出路。
針對rar的解壓縮,我們通常使用winrar,幾乎每臺機器都安裝了winrar,對於普通使用者來說它提供基於使用者介面的解壓縮方式,另外,它也提供基於命令列的解壓縮方式,這為我們在程式中解壓縮rar格式提供了一個入口,我們可以在C#程式中呼叫rar的命令列程式實現解壓縮,思路是這樣的:
1、判斷登錄檔確認使用者機器是否安裝winrar程式,如果安裝取回winrar安裝目錄。
2、建立一個命令列執行程序。
3、通過winrar的命令列引數實現解壓縮。
首先我們通過下面的程式碼判斷使用者計算機是否安裝了winrar壓縮工具:
如果已經安裝winrar可通過如下程式碼返回winrar的安裝位置,未安裝則返回空字串,最後並關閉登錄檔:
public static string ExistsWinRar() { string result = string.Empty; string key = @"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\WinRAR.exe"; RegistryKey registryKey = Registry.LocalMachine.OpenSubKey(key); if (registryKey != null) { result = registryKey.GetValue("").ToString(); } registryKey.Close(); return result; }
/// <summary> /// 將格式為rar的壓縮檔案解壓到指定的目錄 /// </summary> /// <param name="rarFileName">要解壓rar檔案的路徑</param> /// <param name="saveDir">解壓後要儲存到的目錄</param> public static void DeCompressRar(string rarFileName, string saveDir) { string regKey = @"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\WinRAR.exe"; RegistryKey registryKey = Registry.LocalMachine.OpenSubKey(regKey); string winrarPath = registryKey.GetValue("").ToString(); registryKey.Close(); string winrarDir = System.IO.Path.GetDirectoryName(winrarPath); String commandOptions = string.Format("x {0} {1} -y", rarFileName, saveDir); ProcessStartInfo processStartInfo = new ProcessStartInfo(); processStartInfo.FileName = System.IO.Path.Combine(winrarDir, "rar.exe"); processStartInfo.Arguments = commandOptions; processStartInfo.WindowStyle = ProcessWindowStyle.Hidden; Process process = new Process(); process.StartInfo = processStartInfo; process.Start(); process.WaitForExit(); process.Close(); }
/// <summary> /// 將目錄和檔案壓縮為rar格式並儲存到指定的目錄 /// </summary> /// <param name="soruceDir">要壓縮的資料夾目錄</param> /// <param name="rarFileName">壓縮後的rar儲存路徑</param> public static void CompressRar(string soruceDir, string rarFileName) { string regKey = @"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\WinRAR.exe"; RegistryKey registryKey = Registry.LocalMachine.OpenSubKey(regKey); string winrarPath = registryKey.GetValue("").ToString(); registryKey.Close(); string winrarDir = System.IO.Path.GetDirectoryName(winrarPath); String commandOptions = string.Format("a {0} {1} -r", rarFileName, soruceDir); ProcessStartInfo processStartInfo = new ProcessStartInfo(); processStartInfo.FileName = System.IO.Path.Combine(winrarDir, "rar.exe"); processStartInfo.Arguments = commandOptions; processStartInfo.WindowStyle = ProcessWindowStyle.Hidden; Process process = new Process(); process.StartInfo = processStartInfo; process.Start(); process.WaitForExit(); process.Close(); }
在C#.NET中壓縮解壓zip檔案
zip是一種免費開源的壓縮格式,windows平臺自帶zip壓縮和解壓工具,由於演算法是開源的,所以基於zip的解壓縮開源庫也很多,SharpZipLib是一個很不錯的C#庫,它能夠解壓縮zip、gzip和tar格式的檔案,首先下載SharpZipLib解壓後,在您的專案中引用ICSharpCode.SharpZLib.dll程式集即可,下面是一些關於SharpZipLib壓縮和解壓的示例。
ZipOutputStream zipOutStream = new ZipOutputStream(File.Create("my.zip")); CreateFileZipEntry(zipOutStream, "file1.txt", "file1.txt"); CreateFileZipEntry(zipOutStream, @"folder1\folder2\folder3\file2.txt", "file2.txt"); zipOutStream.Close();
Directory.CreateDirectory("ZipOutPut"); ZipInputStream zipInputStream = new ZipInputStream(File.Open("my.zip", FileMode.Open)); ZipEntry zipEntryFromZippedFile = zipInputStream.GetNextEntry(); while (zipEntryFromZippedFile != null) { if (zipEntryFromZippedFile.IsFile) { FileInfo fInfo = new FileInfo(string.Format("ZipOutPut\\{0}", zipEntryFromZippedFile.Name)); if (!fInfo.Directory.Exists) fInfo.Directory.Create(); FileStream file = fInfo.Create(); byte[] bufferFromZip = new byte[zipInputStream.Length]; zipInputStream.Read(bufferFromZip, 0, bufferFromZip.Length); file.Write(bufferFromZip, 0, bufferFromZip.Length); file.Close(); } zipEntryFromZippedFile = zipInputStream.GetNextEntry(); } zipInputStream.Close();
使用.NET中自帶的類解壓縮zip檔案
微軟在System.IO.Compression名稱空間有一些關於檔案解壓縮的類,如果只是希望壓縮解壓zip和gzip格式的檔案,是個不錯的選擇,在NET Framework 4.5框架中,原生System.IO.Compression.FileSystem.dll程式集中新增了一個名為ZipFile的類,,讓壓縮和解壓zip檔案變得更簡單,ZipFile的使用示例如下:
System.IO.Compression.ZipFile.CreateFromDirectory(@"e:\test", @"e:\test\test.zip"); //壓縮
System.IO.Compression.ZipFile.ExtractToDirectory(@"e:\test\test.zip", @"e:\test"); //解壓
支援格式最多的C#解壓縮開源庫
當您還苦苦在為上面的各種壓縮格式發愁的時候,一個名為SharpCompress的C#框架被開源,您可以在搜尋引擎中找到SharpCompress框架的開原始碼,它支援:rar 7zip, zip, tar, tzip和bzip2格式的壓縮和解壓,下面的示例直接從rar格式檔案讀取並解壓檔案。
using (Stream stream = File.OpenRead(@"C:\Code\sharpcompress.rar")) { var reader = ReaderFactory.Open(stream); while (reader.MoveToNextEntry()) { if (!reader.Entry.IsDirectory) { Console.WriteLine(reader.Entry.FilePath); reader.WriteEntryToDirectory(@"C:\temp"); } } }
零度最後的總結
關於rar和zip格式相比,rar的壓縮率比zip要高,而且支援分卷壓縮,但rar是商業軟體,需要付費,zip壓縮率不如rar那麼高,但開源免費,7zip格式開源免費,壓縮率較為滿意,這些壓縮格式各有優勢,就微軟平臺和一些開源平臺來說,一般採用的都是zip格式,因為它更容易通過程式設計的方式實現,比rar更加可靠,以上就是零度為您推薦的C#解壓縮框架,感謝閱讀,希望對您有所幫助。
/// <summary>
/// 解壓RAR和ZIP檔案(需存在Winrar.exe(只要自己電腦上可以解壓或壓縮檔案就存在Winrar.exe))
/// </summary>
/// <param name="UnPath">解壓後文件儲存目錄</param>
/// <param name="rarPathName">待解壓檔案存放絕對路徑(包括檔名稱)</param>
/// <param name="IsCover">所解壓的檔案是否會覆蓋已存在的檔案(如果不覆蓋,所解壓出的檔案和已存在的相同名稱檔案不會共同存在,只保留原已存在檔案)</param>
/// <param name="PassWord">解壓密碼(如果不需要密碼則為空)</param>
/// <returns>true(解壓成功);false(解壓失敗)</returns>
public
static
bool
UnRarOrZip(
string
UnPath,
string
rarPathName,
bool
IsCover,
string
PassWord)
{
if
(!Directory.Exists(UnPath))
Directory.CreateDirectory(UnPath);
Process Process1 =
new
Process();
Process1.StartInfo.FileName =
"Winrar.exe"
;
Process1.StartInfo.CreateNoWindow =
true
;
string
cmd =
""
;
if
(!
string
.IsNullOrEmpty(PassWord) && IsCover)
//解壓加密檔案且覆蓋已存在檔案( -p密碼 )
cmd =
string
.Format(
" x -p{0} -o+ {1} {2} -y"
, PassWord, rarPathName, UnPath);
else
if
(!
string
.IsNullOrEmpty(PassWord) && !IsCover)
//解壓加密檔案且不覆蓋已存在檔案( -p密碼 )
cmd =
string
.Format(
" x -p{0} -o- {1} {2} -y"
, PassWord, rarPathName, UnPath);
else
if
(IsCover)
//覆蓋命令( x -o+ 代表覆蓋已存在的檔案)
cmd =
string
.Format(
" x -o+ {0} {1} -y"
, rarPathName,UnPath);
else
//不覆蓋命令( x -o- 代表不覆蓋已存在的檔案)
cmd =
string
.Format(
" x -o- {0} {1} -y"
, rarPathName, UnPath);
//命令
Process1.StartInfo.Arguments = cmd;
Process1.Start();
Process1.WaitForExit();
//無限期等待程序 winrar.exe 退出
//Process1.ExitCode==0指正常執行,Process1.ExitCode==1則指不正常執行
if
(Process1.ExitCode == 0)
{
Process1.Close();
return
true
;
}
else
{
Process1.Close();
return
false
;
}
}
/// <summary>
/// 壓縮檔案成RAR或ZIP檔案(需存在Winrar.exe(只要自己電腦上可以解壓或壓縮檔案就存在Winrar.exe))
/// </summary>
/// <param name="filesPath">將要壓縮的資料夾或檔案的絕對路徑</param>
/// <param name="rarPathName">壓縮後的壓縮檔案儲存絕對路徑(包括檔名稱)</param>
/// <param name="IsCover">所壓縮檔案是否會覆蓋已有的壓縮檔案(如果不覆蓋,所壓縮檔案和已存在的相同名稱的壓縮檔案不會共同存在,只保留原已存在壓縮檔案)</param>
/// <param name="PassWord">壓縮密碼(如果不需要密碼則為空)</param>
/// <returns>true(壓縮成功);false(壓縮失敗)</returns>
public
static
bool
CondenseRarOrZip(
string
filesPath,
string
rarPathName,
bool
IsCover,
string
PassWord)
{
string
rarPath = Path.GetDirectoryName(rarPathName);
if
(!Directory.Exists(rarPath))
Directory.CreateDirectory(rarPath);
Process Process1 =
new
Process();
Process1.StartInfo.FileName =
"Winrar.exe"
;
Process1.StartInfo.CreateNoWindow =
true
;
string
cmd =
""
;
if
(!
string
.IsNullOrEmpty(PassWord) && IsCover)
//壓縮加密檔案且覆蓋已存在壓縮檔案( -p密碼 -o+覆蓋 )
cmd =
string
.Format(
" a -ep1 -p{0} -o+ {1} {2} -r"
, PassWord, rarPathName, filesPath);
else
if
(!
string
.IsNullOrEmpty(PassWord) && !IsCover)
//壓縮加密檔案且不覆蓋已存在壓縮檔案( -p密碼 -o-不覆蓋 )
cmd =
string
.Format(
" a -ep1 -p{0} -o- {1} {2} -r"
, PassWord, rarPathName, filesPath);
else
if
(
string
.IsNullOrEmpty(PassWord) && IsCover)
//壓縮且覆蓋已存在壓縮檔案( -o+覆蓋 )
cmd =
string
.Format(
" a -ep1 -o+ {0} {1} -r"
, rarPathName, filesPath);
else
//壓縮且不覆蓋已存在壓縮檔案( -o-不覆蓋 )
cmd =
string
.Format(
" a -ep1 -o- {0} {1} -r"
, rarPathName, filesPath);
//命令
Process1.StartInfo.Arguments = cmd;
Process1.Start();
Process1.WaitForExit();
//無限期等待程序 winrar.exe 退出
//Process1.ExitCode==0指正常執行,Process1.ExitCode==1則指不正常執行
if
(Process1.ExitCode == 0)
{
Process1.Close();
return
true
;
}
else
{
Process1.Close();
return
false
;
}
}