2008-09-19 48 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。

相关问题