2008-09-19 70 views
19

拉上什麼是非ASCII文件名添加到使用的Java,以這樣的方式,該文件可以被正確讀取的zip文件的最佳方式都是WindowsLinux?添加非ASCII文件名中的Java

下面是一個嘗試,改編自https://truezip.dev.java.net/tutorial-6.html#Example,它適用於Windows Vista,但在Ubuntu Hardy中失敗。在Hardy中,文件名稱在文件滾輪中顯示爲abc-ЖДФ.txt。

import java.io.IOException; 
import java.io.PrintStream; 

import de.schlichtherle.io.File; 
import de.schlichtherle.io.FileOutputStream; 

public class Main { 

    public static void main(final String[] args) throws IOException { 

     try { 
      PrintStream ps = new PrintStream(new FileOutputStream(
        "outer.zip/abc-åäö.txt")); 
      try { 
       ps.println("The characters åäö works here though."); 
      } finally { 
       ps.close(); 
      } 
     } finally { 
      File.umount(); 
     } 
    } 
} 

與java.util.zip不同,truezip允許指定zip文件編碼。這是另一個示例,這次明確指定了編碼。 IBM437,UTF-8和ISO-8859-1都不適用於Linux。 IBM437在Windows中工作。

import java.io.IOException; 

import de.schlichtherle.io.FileOutputStream; 
import de.schlichtherle.util.zip.ZipEntry; 
import de.schlichtherle.util.zip.ZipOutputStream; 

public class Main { 

    public static void main(final String[] args) throws IOException { 

     for (String encoding : new String[] { "IBM437", "UTF-8", "ISO-8859-1" }) { 
      ZipOutputStream zipOutput = new ZipOutputStream(
        new FileOutputStream(encoding + "-example.zip"), encoding); 
      ZipEntry entry = new ZipEntry("abc-åäö.txt"); 
      zipOutput.putNextEntry(entry); 
      zipOutput.closeEntry(); 
      zipOutput.close(); 
     } 
    } 
} 
+0

truezip使用UTF-8爲我工作在Windows 7和Mac OS X 10.6.x.它仍然不能在Linux中工作? – 2009-11-23 17:37:34

+1

存在一個長期存在的bug - 存在9年 - 在v7之前的JDK中,它阻止了正確處理名稱不能用IBM CP437編碼的文件名。 http://bugs.sun.com/bugdatabase/view_bug.do?bug%5Fid=4244499它顯然已在JDK7中修復。 https://blogs.oracle.com/xuemingshen/entry/non_utf_8_encoding_in因此,一種解決方案似乎是使用JDK7和ZipInputStream,ZipOutputStream和ZipFile的新構造函數。 – Cheeso 2012-06-15 16:53:56

回答

0

它實際上是失敗還是隻是一個字體問題? (例如對於這些字符具有不同字形的字體)我在Windows中看到類似的問題,因爲字體不支持charset,但是數據實際上是完整正確的。

+0

感謝您的回覆,它不是字體問題,因爲我可以創建一個類似的文件,然後將其壓縮並正確顯示。 – Micke 2008-09-19 23:36:05

0

非ASCII文件名在ZIP實現中不可靠,最好避免。沒有關於在ZIP文件中存儲字符集設置的規定;客戶傾向於用'當前系統代碼頁'來猜測,這不太可能是你想要的。客戶端和代碼頁的許多組合可能會導致無法訪問的文件。

對不起!

+0

根據PKWare的規範,有一條規定注意到文件名是用UTF-8編碼的。壓縮文件中的UTF-8編碼尚未得到廣泛支持(==尚未在Windows資源管理器中受支持)。 當UTF-8位是在zip條目報頭未設置,則壓縮規範說的文件名應在IBM437進行編碼。但是你是正確的,一些應用程序(WinRar)只是用系統默認代碼頁進行編碼。不確定Windows資源管理器是否執行此操作讀取zip時不使用正確的編碼實際上會導致無法訪問的文件。 – Cheeso 2009-05-19 15:20:59

10

的文件條目的ZIP編碼最初指定爲IBM的代碼頁437.在其他語言中使用的很多人物都不可能使用這種方式。

PKWARE-specification指的是問題,並增加了一點。但是這是後來的增加(從2007年開始,感謝Cheeso對此進行清理,請參閱評論)。如果該位被設置,則文件名項必須以UTF-8編碼。該擴展在「附錄D - 語言編碼(EFS)」中進行了介紹,該鏈接位於鏈接文檔的末尾。

對於Java來說,這是一個已知的錯誤,用非ASCII字符來解決問題。請參閱bug #4244499以及大量相關的錯誤。

我的同事在將它們存儲到ZIP中並在讀取它們之後進行解碼之前,將它們用作文件名的解決方法URL-Encoding。如果您同時控制,存儲和讀取,這可能是一種解決方法。

編輯:在錯誤有人建議使用Apache Ant的ZipOutputStream作爲解決方法。該實現允許指定編碼。

+0

「似乎在歷史上被指定爲IBM CP437」有點鬆動。 PKWare規範說,文件名使用IBM437編碼,句點。在2007年,PKWare增加了一種使用UTF-8的標準方式。有些工具既不使用,但超出了規範! – Cheeso 2009-03-28 08:22:45

+1

感謝您的澄清,我改變了答案。 – Mnementh 2009-03-30 11:33:23

8

在Zip文件,根據PKWARE,文件名和文件註釋的編碼所擁有的規範是IBM437。在2007年,PKWare擴展了規範,允許UTF-8。這沒有說明zip中包含的文件的編碼。只有文件名的編碼。

我認爲所有的工具和庫(Java和不支持Java)支持IBM437(這是ASCII的一個超集),以及較少的工具和庫支持UTF-8。一些工具和庫支持其他代碼頁。例如,如果您在運行在上海的計算機上使用WinRar壓縮某些內容,您將獲得Big5代碼頁。這不是zip規範「允許的」,但它無論如何都會發生。

DotNetZip庫.NET確實Unicode的,當然它不能幫助你,如果你使用的是Java!

使用Java內置了對ZIP支持,你總是會得到IBM437。如果您想使用IBM437以外的其他存檔,請使用第三方庫或創建JAR。

相關問題