Java读写Unicode/UTF-8文件名(而非内容)

7
我有一些包含日文字符的目录/文件。如果我尝试读取一个文件名(而不是内容)包含(例如)一个ク,我会得到一个包含�的字符串。如果我尝试创建包含ク的文件/目录,则会出现一个包含?的文件/目录。
例如: 我使用以下命令列出文件。
File file = new File(".");  
String[] filesAndDirs = file.list();

文件和目录数组现在包含了这些特殊字符的目录。字符串现在只包含����。看起来没有什么可解码的,因为a getbytes对于文件名中的每个字符甚至不同的字符都只显示“-17 -65 -67”。

我使用的是MacOS 10.8.2 Java 7_10和Netbeans。

有什么想法吗?

提前感谢您:)


2
不清楚你是如何显示这些文件名的,也不清楚你是否为String.getBytes()提供了编码(你应该始终这样做)。你应该输出每个文件名中每个字符的UTF-16代码点,以查看实际情况。此外,在尝试创建文件时,也不清楚你是如何获取输入数据的。 - Jon Skeet
getBytes 返回的似乎是有效的 UTF8。 - John Dvorak
1
@Jan 是的,它看起来像是有效的UT8,但getBytes对于每个字符返回“-17 -65 -67”。但文件/目录名称中并非所有字符都相同。似乎我失去了操作系统和JavaVM之间的所有信息。“-17 -65 -67”在每个特殊字符中都重复出现。[a-zA-Z ...]按预期返回。我至少希望每个字符有不同的字节。 - uti.devel
也许这是有效的UTF8编码,用于某个字符。 - John Dvorak
2个回答

4
那些字节是0xef 0xbf 0xbd,这是你看到的\ufffd字符的UTF-8编码形式,而不是日语字符。似乎Java使用列出文件的操作系统功能已返回这些错误字符。也许Files.newDirectoryStream会更可靠。请尝试这个替代方法:
try (DirectoryStream<Path> dir = Files.newDirectoryStream(Paths.get("."))) {
    for (Path child : dir) {
        String filename = child.getFileName().toString();

        System.out.println("name=" + filename);
        for (char c : filename.toCharArray()) {
            System.out.printf("%04x ", (int) c);
        }
        System.out.println();
    }
}

1
运行得非常好 :). 现在我只需要找出如何创建带有特殊字符的文件和文件夹。非常感谢! - uti.devel
看一下Files类的javadoc。它有方法可以做所有这些事情。 - VGR

2

这是旧的Java文件API中的一个错误(可能只在Mac上出现)。无论如何,在新的java.nio中都已经全部修复了。

我有几个包含Unicode字符的文件名和内容,使用java.io.File和相关类加载失败。将所有代码转换为使用java.nio.Path后,一切都开始正常工作。我还用java.nio.Files替换了具有相同问题的org.apache.commons.io.FileUtils...

...并确保使用适当的字符集读取和写入文件内容,例如:Files.readAllLines(myPath, StandardCharsets.UTF_8)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接