2013-04-22 184 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