自动创建多部分 Zip 文件
自动创建分卷 Zip 文件。
引言
文件共享网站上的大多数访客账户在可上传文件大小上都有 100 – 300 MB 的限制。我通常使用 WinZip 的分卷选项来压缩我要上传的文件。有时,上传到文件共享网站可能会遇到问题。如果您上传的文件是使用分卷选项创建的,这意味着下载者需要下载所有分卷才能解压文件。我希望我共享的图片文件在下载后即可查看,而无需等待所有压缩包分卷都可用。我也不想在创建和添加 Zip 压缩包时手动猜测总文件大小限制。因此,我决定编写一个实用程序,该程序可以根据用户可选择的预定义分区(100MB、500MB、1000MB)或用户自定义的分区大小,自动创建分卷 Zip 压缩包。用户选择要压缩的文件,然后根据定义的分区大小,程序会自动为您创建分卷 Zip 压缩包。
系统概述
该实用程序是用 C# 编写的。为了创建 Zip 压缩包,我使用了 SharpZipLib [3] 库。这是一个用 C# 编写的开源 Zip、GZip、Tar 和 BZip2 压缩库。为了进行日志记录和调试,我使用了 NLog [2] 库。此实用程序的用例如图 1 所示。ZipMaker 允许用户批量或单独选择他/她希望压缩的文件。还可以指定目标目录和要保存的结果压缩包名称。如果未指定这些,系统将根据 UUID 自动生成文件名,并将文件保存在应用程序运行的目录中。此外,用户还可以选择压缩级别(1 – 9);9 为最佳。还可以由用户指定文件分区大小。因此,例如,如果您选择了 100 个文件要压缩,总大小为 350MB,并且选定的分区大小为 100MB,那么将创建四个 Zip 文件,每个 Zip 压缩包的大小将为 100MB 或更小。如果这两个参数都未指定,则将使用默认的压缩级别(9)和分区文件大小(100 MB)。
设计
ZipMaker 由四个模块组成。图 2 中的类图显示了构成此实用程序的组件及其关系。主 UI 窗体是 ZipMakerForm
;它处理所有用户交互。此外,我还使用了 [1],它在执行压缩操作时显示一个进度对话框。ZipMakerForm
类有几个属性。它们显示如下
private long totalFileSize = 0L; /* In bytes */
private long totalNumberFilesSelected = 0L; /* Total number of files selected */
private int partitionSize; /* In MegaBytes */
private int partitionSizeInBytes = 100000000; /* defaulted to 100 MB */
private int compressionLevel = 9; /* defaults to 9 (best) */
private String saveFileBase = ""; /* Zip file to save as */
private ArrayList fileInfoList;
private ArrayList fileIndices = new ArrayList();
totalFileSize
记录要压缩文件的总大小;totalNumberFilesSelected
存储用户选择要压缩的文件的总数;partitionSize
以兆字节为单位捕获用户指定的文件归档分区大小;partitionSizeInBytes
是从兆字节到字节的转换因子;compressionLevel
是一个 1-9 的整数,用于设置 Zip 压缩级别;saveFileBase
用于指定要保存的压缩包的根文件名;fileInfoList
用于将用户选择的文件属性存储到 ArrayList 中。fileIndices
是一个 ArrayList,用于引用分卷压缩包的终点。
如果只有一个压缩包,则压缩包名称将采用 saveFileBase
的值;否则,根据计算出的压缩包数量,基础名称后面会附加一个数字,直到计算出的压缩包总数。因此,以上面的例子为例,用户选择了 100 个文件要压缩,总大小为 350MB,分区大小为 100MB,将创建四个 Zip 文件,每个 Zip 压缩包的大小为 100MB 或更小。如果 saveFileBase
属性的值是 testZipMaker
,那么这四个 Zip 压缩包将分别命名为:testZipMaker_1.zip、testZipMaker_2.zip、testZipMaker_3.zip 和 testZipMaker_4.zip。
ArrayList 的每个项都存储一个 FileInfoItem
对象,该对象包含文件名、大小和目录位置。最后,
在上面描述的四个 Zip 压缩包示例中,第一个 Zip 压缩包存储终点 30,第二个 50,第三个 80,最后一个 100。我们使用 fileIndices
ArrayList 中的值来引用 fileInfoList
数组以执行实际的压缩操作。
此类中的主要方法是
private int computeNumberOfArchives()
private void createZipArchive()
private void doZip()
当用户单击“Zip”按钮(毕竟参数已设置)时,将调用 createZipArchive()
方法。createZipArchive()
又调用 doZip()
,后者使用 [3] 中的 API 执行实际的压缩操作。由于我还想在压缩操作进行时提供某种用户反馈,因此进度条回调(Begin
、StepTo
和 End
)也嵌入在这两个方法中。我从 [1] 修改了这一点,以便将此组件集成到我的应用程序中。computeNumberOfArchives()
方法计算需要创建的 Zip 压缩包的数量。
用户界面流程
当 ZipMaker 应用程序启动时,将向用户显示以下窗体。按下 Browse 按钮会弹出 File Open 对话框,允许用户选择他/她希望压缩的文件。在选择要压缩的文件后,这些文件将显示在列表框中(在图 4 中用红色圈出)。用户还可以更改默认设置(文件分区大小和压缩级别)。当他对参数满意后,他/她将单击“Save As”按钮来指定要保存的目标目录和压缩包文件名。单击“Zip”按钮将激活压缩操作。图 5 中的进度条在存档操作进行时提供某种用户反馈。
结论
我展示了一个简单的实用程序,用于根据用户可指定或预先选择的分区大小来创建单个或分卷 Zip 压缩包。希望您发现此实用程序很有用。