如何将多个文件夹压缩成一个存档?

时间:2013-04-22 21:12:35

标签: delphi zip archive subdirectory delphi-xe3

我有一些压缩组件(如KAZip,JVCL,zLib)并且确切知道如何使用它们来压缩文件,但我想将多个文件夹压缩成一个单独的存档并在提取后保留文件夹结构,我该怎么做呢?


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

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

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

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

1 个答案:

答案 0 :(得分:4)

zip格式没有文件夹。嗯,它确实有,但它们是一种空的占位符,只有在需要元数据存储(如用户访问权限)时才会插入。但除了那些相当罕见的高级东西之外 - 根本不需要文件夹。真正做到了 - 你可以在记事本中看到打开zip文件并滚动到最后 - 是每个文件都有自己的路径,从“archive root”开始。在你的例子中,zip文件应该有两个条目(两个文件):

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

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

现在,让我们假设该树包含在D:\TEMP\Project中 - 仅举例来说。

  • d:\ TEMP \项目\ FOLDER_A \ myText.txt
  • d:\ TEMP \项目\ FOLDER_B \ myText.txt

还有两个问题(路径分隔符除外):D:\TEMP\Project\中是否有更多文件夹应该被忽略,而不是压缩(如D:\TEMP\Project\FOLDER_C\*.*}?并且您的zip库是否直接用于打包文件夹的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

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

    上一版本页面包含“setup”包的链接,其中包含源代码,帮助和演示。在演示中,有一个功能齐全的存档浏览器,能够存储文件夹。所以,您只需直接从中读取代码即可。 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而不是磁盘上的文件,所以不会直接帮助你。但我刚刚学到的东西比在地面上的一些怪癖(如即时与推迟的拉链)有所不同,所有这些库都是一样的。