2009-12-02 55 views
4

這些日子人們用WinZIP創建了他們的ZIP壓縮文件,它允許國際化(即非拉丁文:西里爾文,希臘文,中文,你的名字)文件名。使用I18N文件名解壓用WinZIP創建的文件?

不幸的是,試圖解壓這樣的文件會造成麻煩: UNIX unzip會創建垃圾命名文件和像「®£¤¥èì」這樣的dirs。 Java和它的jar命令在這樣的檔案上失敗了。

有沒有一種可以通過編程方式解壓縮這些文件的方法? UNIX或Java。

回答

2

我找到的解決方案: Apache commons-compress可以解壓縮這些壓縮文件,只要提供了正確的後備字符集即可。

3

DotNetZip支持zip文件中的文件名的unicode和任意編碼,用於讀取或寫入zip文件。

這是一個.NET庫。對於Unix使用,您需要Mono作爲先決條件。

如果zip文件是由WinZip正確構建的,換句話說,如果它符合the zip spec from PKWare,那麼在解壓縮文件時就不需要做特殊的工作來指定編碼。根據zip規範,在zipfiles中有兩種用於文件名的支持編碼:UTF-8和IBM437。這些編碼中的一個或另一個的使用在zip元數據中指定,並且任何zip庫可以檢測並使用它。 DotNetZip在閱讀合規郵編時會自動檢測到它。像這樣:

using (var zip = ZipFile.Read("thearchive.zip")) 
{ 
    foreach (var e in zip) 
    { 
     // e.FileName refers to the name on the entry 
     e.Extract("extract-directory"); 
    } 
} 

有一些存檔程序產生「不符合」w.r.t的zip文件。編碼。 WinRar就是其中之一 - 它會創建一個zip文件,該文件的文件名以計算機上使用的默認編碼編碼。在上海,它將使用CP950,而冰島則使用其他產品,而在里斯本則使用其他產品。這裏「不符合」的好處是Windows資源管理器將打開並正確顯示這些zip文件中的國際化文件名。換句話說,「不符合」通常是人們想要的,因爲Windows不支持(還)?支持UTF-8 zip文件。

(這一切都與在壓縮文件中使用的編碼,而不是包含在壓縮文件中的文件使用的編碼做)

拉鍊規範不允許任意文本編碼規範在zip元數據中。換句話說,如果您在創建zip時使用cp950,那麼您的提取邏輯需要「知道」在提取時使用cp950 - zip文件中沒有任何信息攜帶該信息。另外,當然,用於以編程方式提取的zip庫必須支持任意編碼。據我所知,Java的zip庫沒有。 DotNetZip的確。像這樣:

using (ZipFile zip = ZipFile.Read(zipToExtract, 
            System.Text.Encoding.GetEncoding(950))) 
{ 
    foreach (ZipEntry e in zip) 
    { 
    e.Extract(extractDirectory); 
    } 
} 

DotNetZip還可以創建任意編碼的zip文件 - 「不符合」的拉鍊。

DotNetZip是免費的,而且是開源的。

+1

謝謝,但安裝7z更容易,因爲它已經在存儲庫中。 – alamar 2009-12-07 09:35:14