C# 携手 7-Zip 命令行:大文件压缩的终极武器?
前言
嗨,大家好!
今天咱们来聊聊如何用 C# 调用 7-Zip 命令行来压缩大文件,这是个既高效又稳定的好办法,亲测有效!
在实际工作中,压缩文件几乎是家常便饭,但可惜的是,许多常用的方法并不如我们所愿,稍不注意,就会踩 “坑”,我以前就踩了不少 “坑”,比如说:
-
用 C# 内置的压缩方法,效率低不说,资源占用还高,尤其是一旦文件超过 2GB 就会频繁出错,而且,它的功能简单得可怜,对于复杂的需求(比如分卷压缩、加密等)几乎无能为力。
-
我还尝试过使用 NuGet 上的第三方库(比如 ZipStorer),但是没想到一旦文件总大小超过 4G,压缩出来的文件常常有各种奇奇怪怪的问题,根本解压不了!
幸运的是,我后来选择直接使用 7-Zip 的命令行来压缩文件。
结果令人惊喜:不仅压缩速度极快,而且输出文件的稳定性也大幅提升,完全不用担心解压问题。
下面就让我来分享一下具体的操作步骤吧!
Step By Step 代码
-
编写一个打开 CMD 窗口执行一段命令行脚本的方法
public static class CommandUtil {/// <summary>/// 调用 CMD 窗口执行一段命令行脚本/// </summary>/// <param name="commandLine">命令行脚本</param>/// <param name="errorMsg">错误消息</param>/// <param name="errorMsg">输出消息</param>/// <returns>返回命令执行是否成功状态</returns>public static bool ExecuteCmdCommand(string commandLine, ref string errorMsg, ref string outputMsg){bool Flag = false;Process proc = new Process();try{// 配置CMD窗口的启动信息proc.StartInfo.FileName = "cmd.exe";proc.StartInfo.UseShellExecute = false; // 不使用操作系统的外部程序proc.StartInfo.RedirectStandardInput = true;// 开启重定向输入proc.StartInfo.RedirectStandardOutput = true;// 开启重定向输出proc.StartInfo.RedirectStandardError = true;// 开启重定向错误输出proc.StartInfo.CreateNoWindow = true; // 不创建窗口proc.Start();proc.StandardInput.WriteLine(commandLine);// 写入命令proc.StandardInput.WriteLine("exit");// 完成后退出errorMsg = proc.StandardError.ReadToEnd();// 捕获错误信息outputMsg = proc.StandardOutput.ReadToEnd();// 捕获输出信息proc.WaitForExit(); // 等待进程退出if (proc.ExitCode == 0){Flag = true;}proc.StandardError.Close();}catch (Exception ex){throw;}finally{proc.Close();proc.Dispose();}return Flag;} }
-
创建一个封装调用 7-Zip 的密封类
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using Common.Util;namespace ZipCommon {public sealed class SevenZipUtil{/// <summary>/// 压缩方法/// </summary>/// <param name="cmdFormat">命令行脚本</param>/// <param name="sourceFolder">源文件目录</param>/// <param name="outZipFile">要输出的压缩文件</param>/// <returns></returns>private static void ZipUsing7zip(string cmdFormat, string sourceFolder, string outZipFile){try{// 找到 7z.exe 的路径string zipExePath = Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase, "bin", "7-zip", "7z.exe");// 获取要压缩的文件string filesPath = Path.Combine(sourceFolder, "*");// 格式化命令string cmd = string.Format(cmdFormat, zipExePath, outZipFile, filesPath);// 调用 7-Zip 执行命令string errorMsg = "";string outputMsg = "";bool cmdResult = CommandUtil.ExecuteCmdCommand(cmd, ref errorMsg, ref outputMsg);if (!cmdResult){string exceptionMsg = "压缩文件时发生错误。";if (!string.IsNullOrWhiteSpace(errorMsg)) exceptionMsg = string.Format("{0} [{1}]", exceptionMsg, errorMsg);throw new Exception(exceptionMsg);}} catch (Exception ex) { throw new Exception("压缩文件时发生错误。", ex); } }/// <summary> /// 压缩方法(单文件夹) /// </summary> /// <param name="sourceFolder">源文件目录</param> /// <param name="outZipFile">要输出的压缩文件</param> /// <returns></returns> public static void ZipLargeFiles(string sourceFolder, string outZipFile) { try { string cmdFormat = "\"{0}\" a -tzip -mx=0 -mmt=on \"{1}\" \"{2}\""; ZipUsing7zip(cmdFormat, sourceFolder, outZipFile); } catch { throw; } }/// <summary> /// 压缩方法(文件字典集合) /// </summary> /// <param name="fileList">文件字典集合</param>/// <param name="outZipFile">要输出的压缩文件</param> /// <returns></returns> public static void ZipLargeFiles(Dictionary<string, string> fileList, string outZipFile) { try { // 1. 创建一个临时目录用来存放文件字典集合里的文件 string tempDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "tmp_dir", "zipping", DateTime.Now.ToString("yyyyMMddHHmmssffffff")); if (!Directory.Exists(tempDir)) Directory.CreateDirectory(tempDir);// 2. 拷贝文件字典集合里的文件到临时目录 foreach (KeyValuePair<string, string> filepath in fileList) { File.Copy(filepath.Key, Path.Combine(tempDir, filepath.Value)); }// 3. 调用 7-Zip 压缩文件 string cmdFormat = "\"{0}\" a -tzip -mx=0 -mmt=on \"{1}\" \"{2}\" -sdel"; ZipUsing7zip(cmdFormat, tempDir, outZipFile);// 4. 删除临时目录 Directory.Delete(tempDir, true); } catch { throw; } } } }
-
使用
// 待压缩文件目录 var filespath = @"D:\largeFile";// 压缩后输出的压缩文件 var outfile = @"D:\ZipTest\largeFile.zip";// 调用压缩方法 SevenZipUtil.ZipLargeFiles(filespath, outfile);
-
注意事项
- 确保项目在编译时将 7z.exe 一起输出到 bin 目录,以防缺失文件导致程序出错。
7-Zip 命令参数说明
解释一下以上命令行里的参数:
- a:添加文件到压缩包里。
- -tzip:指定压缩类型为 zip,这是操作系统内置支持的格式,此外还可以设置为其他格式如 7z、gzip 等。
- -mx=0:设置压缩级别为 0,表示复制模式(无压缩),以获得最快的压缩速度。
- -mmt=on:启用多线程模式,适用于多处理器或多核系统,以提高压缩速度。
- -sdel:设置压缩后删除源文件。
总结
使用 7-Zip 命令行来压缩文件,不仅效率更高,而且稳定性更强。
7-Zip 命令行支持多线程,可以充分利用多核处理器的优势,同时提供了多种压缩格式的选择,让你可以根据实际情况灵活调整。无论是处理超大文件还是复杂需求,它都能轻松应对。
总的来说,7-Zip 的命令行工具就像是压缩界的瑞士军刀,功能强大且灵活多样。如果你还在为大文件的压缩头疼,不妨试试这个方法,相信它会让你的工作变得更加高效便捷!
最后,希望这个小技巧能帮你提升工作效率,如果你有更好的经验分享,欢迎留言讨论!
往期精彩
- 闲话 .NET(7):.NET Core 能淘汰 .NET FrameWork 吗?
- 常用的 4 种 ORM 框架(EF Core,SqlSugar,FreeSql,Dapper)对比总结
我是老杨,一个执着于编程乐趣、至今奋斗在一线的 10年+ 资深研发老鸟,是软件项目管理师,也是快乐的程序猿,持续免费分享全栈实用编程技巧、项目管理经验和职场成长心得。欢迎关注老杨的公众号,和你共同探索代码世界的奥秘!