2013-04-22 187 views
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)但我不能给解压缩文件的结构,什么是最好的方法找到哪个文件属于哪个文件夹?

+2

你究竟想做什么?你在寻找什么样的格式。 FWIW最好的工具是tpAbbrevia。 – 2013-04-22 21:26:54

+0

问题修改得更清楚,希望是。并且tpAbbrevia是否支持UTF文件名? – Armin 2013-04-22 21:49:23

+1

那么,我仍然只是使用tpAbbrevia。你真的关心档案是什么格式吗?这就是我所掌握的。有很多不同的格式。任何压缩都可以吗?那么tar + gzip呢?这对你会好吗? – 2013-04-22 21:54:02

回答

4

压缩格式只是没有文件夹。好吧,它有点儿,但是它们是空的占位符,只有当你需要像用户访问权限这样的元数据存储时才能插入。但除了那些非常罕见的高级事物之外 - 根本不需要文件夹。什么是真正完成的 - 你可以观察到在记事本中打开zip文件并滚动到最后 - 是每个文件都有它的路径,从“archive root”开始。在你exanple 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-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/

上一版本页面有链接到“setup”软件包,它有源代码,帮助和演示。演示中有一个全功能的归档浏览器,能够存储文件夹。所以,你可以直接从它读取代码。 http://www.delphizip.org/191/v191.html


你刚才谈到JVCL,这意味着你已经安装了绝地CodeLib。和JCL配备了适当的类和函数,通过名称判断可以直接做你想要什么太:function TJclSevenzipCompressArchive.AddDirectory(const PackedName: WideString; const DirName: string = ''; RecurseIntoDir: Boolean = False; AddFilesInDir: Boolean = False): Integer;

其实所有这些库都在基层,而类似的,当我创造XLSX出口,我只是做了一个统一的压缩API,与实际的压缩引擎的安装方式无差别。但它适用于内存中的TStream而不是磁盘上的文件,所以不能直接帮助你。但我只是在地面上学到了除了几个怪癖(如瞬间vs推迟拉链)之外,所有这些库都是一样的。

+0

+1不错的答案。 – 2013-04-23 10:43:03

+0

@Arioch',谢谢,有史以来最完整和详细的答案之一,我试过zipMaster,它的工作,但正如你所说的线程或DLL的麻烦,但JCL工作正常,没有问题,只需要设置几个运行时间设置 – Armin 2013-04-23 17:36:43

+0

@阿明。别客气。还有WinXP原生zip,但代码示例通常用于VB或C#,并将其翻译为Delphi,但不难,但有点乏味。 – 2013-04-24 09:39:19