1

我有一些压缩组件(如 KAZip、JVCL、zLib)并且完全知道如何使用它们来压缩文件,但是我想将多个文件夹压缩到一个存档中并在提取后保持文件夹结构,我该怎么做?


在所有这些组件中,我只能给出一个要压缩的文件列表,我不能给出要提取的文件夹结构,没有办法(或者我找不到)告诉每个文件必须在哪里提取:

我在文件夹 FOLDER_A 中有一个名为 myText.txt 的文件,在文件夹 FOLDER_B 中有一个同名的文件 myText.txt:

|  
|__________ FOLDER_A  
|   |________ myText.txt  
|  
|__________ FOLDER_B  
|   |________ myText.txt  
|  

我可以提供要压缩的文件列表:myList(myText.txt, myText.txt) 但我无法提供解压缩文件的结构,找到哪个文件属于哪个文件夹的最佳方法是什么?

4

1 回答 1

4

zip 格式只是没有文件夹。嗯,它有点,但它们是一种空的占位符,只有在你需要像用户访问权限这样的元数据存储时才插入。但除了那些相当罕见的高级东西 - 根本不需要文件夹。真正做了什么——你可以观察到在记事本中打开 zip 文件并滚动到最后——每个文件都有它的路径,从“归档根”开始。在您的示例中,zip 文件应该有两个条目(两个文件):

  • FOLDER_A/myText.txt
  • FOLDER_B/myText.txt

请注意,使用的分隔符是真正的斜杠,在 UNIX 世界中很常见,而不是在 DOS/Windows 世界中使用的反斜杠。有些库会为您修复反斜杠,有些则不会 - 只是做您的测试。

现在,让我们假设该树包含在D:\TEMP\Project- 仅作为示例。

  • D:\TEMP\Project\FOLDER_A\myText.txt
  • D:\TEMP\Project\FOLDER_B\myText.txt

还有两个问题(路径分隔符除外):其中是否有更多文件夹D:\TEMP\Project\应该被忽略,而不是压缩(比如可能D:\TEMP\Project\FOLDER_C\*.*?并且您的 zip-library 是否有直接 API 来打包文件夹及其内部子文件夹和文件或你应该逐个文件吗?

在选择图书馆时,您应该问自己并检查这三个问题。代码草案会有所不同。

现在让我们开始为库本身起草:


默认变体只是使用 Delphi 本身。

  1. 枚举文件夹中的文件:http://docwiki.embarcadero.com/CodeExamples/XE3/en/DirectoriesAndFilesEnumeraion_(Delphi)
  2. 如果该枚举的结果是从一开始absolute paths就去掉共同点D:\TEMP\Project:类似于If AnsiStartsText('D:\TEMP\Project\', filename) then Delete(filename, 1, Length('D:\TEMP\Project\'));. 您应该获得相对于所选包含位置的路径。特别是如果您不压缩整个路径并且将一些 FOLDER_C 保存在存档之外。
  3. 也许您还应该调用StringReplace将文件名上的 '\' 更改为 '/'
  4. 然后您可以使用http://docwiki.embarcadero.com/Libraries/XE2/en/System.Zip.TZipFile.Add压缩它们- 注意指定正确的相对关系ArchiveFileName,如前所述FOLDER_A/myText.txt

您可以使用 ZipMaster 库。它非常受 VCL 约束,可能会导致使用线程或 DLL 出现问题。但对于简单的应用程序,它只是工作。http://www.delphizip.org/

最后一个版本页面有指向“设置”包的链接,该包有源代码、帮助和演示。在演示中有一个功能齐全的存档浏览器,能够存储文件夹。因此,您可以直接从中读取代码。http://www.delphizip.org/191/v191.html


您谈到了 JVCL,这意味着您已经安装了 Jedi CodeLib。JCL 带有一个适当的类和函数,根据名称判断也可以直接做你想做的事:function TJclSevenzipCompressArchive.AddDirectory(const PackedName: WideString; const DirName: string = ''; RecurseIntoDir: Boolean = False; AddFilesInDir: Boolean = False): Integer;

实际上,所有这些库在基本级别上都非常相似,当我进行 XLSX 导出时,我只是创建了一个统一的压缩 API,它与实际安装的压缩引擎没有区别。但它适用于内存中的 TStream 而不是磁盘文件,因此不会直接帮助您。但是我刚刚了解到,除了地面上的一些怪癖(例如即时与延迟压缩)之外,所有这些库的工作方式都是一样的。

于 2013-04-23T10:06:31.657 回答