C#压缩或解压rar、zip文件方法实例

作者:一叶青晨 时间:2023-10-21 23:00:16 

前言

为了便于文件在网络中的传输和保存,通常将文件进行压缩操作,常用的压缩格式有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更加可靠。


/// <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 ;
    }

}

来源:https://blog.csdn.net/yegshun/article/details/78601632

标签:c#,压缩,解压
0
投稿

猜你喜欢

  • java 中的instanceof用法详解及instanceof是什么意思(推荐)

    2023-06-07 13:52:27
  • Android实现中国象棋游戏(局域网版)

    2023-11-22 16:07:07
  • 浅谈C#多线程简单例子讲解

    2023-06-24 03:03:50
  • C#遍历得到checkboxlist选中值和设置选中项的代码

    2022-10-25 20:52:22
  • 将来会是Python、Java、Golang三足鼎立的局面吗

    2023-11-22 09:18:31
  • Intellij IDEA 2017新特性之Spring Boot相关特征介绍

    2023-06-22 15:13:02
  • Android编程实现自定义进度条颜色的方法

    2023-07-24 07:40:58
  • 深入解析Java接口(interface)的使用

    2022-05-07 07:50:51
  • IDEA修改idea64.exe.vmoptions文件以及解决coding卡顿问题

    2022-11-02 00:36:04
  • SpringBoot + FFmpeg实现一个简单的M3U8切片转码系统

    2023-11-24 19:52:38
  • Android实现人脸支付的示例代码

    2023-07-30 14:23:52
  • C# 抽象类,抽象属性,抽象方法(实例讲解)

    2022-03-14 09:22:16
  • Spring实战之使用注解实现声明式事务操作示例

    2021-08-19 07:16:07
  • Android动态修改应用图标与名称的方法实例

    2021-11-21 13:24:44
  • android通过拼音搜索中文的功能实现代码

    2022-03-12 04:48:17
  • java 数据结构并查集详解

    2023-01-22 03:52:24
  • Java基础教程之String深度分析

    2022-08-19 05:42:15
  • spring cloud 之 客户端负载均衡Ribbon深入理解

    2023-02-15 15:00:58
  • HttpServletResponse乱码问题_动力节点Java学院整理

    2021-10-18 17:48:51
  • Spring Boot环境下Mybatis Plus的快速应用操作

    2023-04-08 13:27:33
  • asp之家 软件编程 m.aspxhome.com