前言
嗨,大家好!
今天咱们来聊聊如何用 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年+ 资深研发老鸟,是软件项目管理师,也是快乐的程序猿,持续免费分享全栈实用编程技巧、项目管理经验和职场成长心得。欢迎关注老杨的公众号,和你共同探索代码世界的奥秘!