12

我正在处理对文件执行各种 IO 操作的代码,并且我想让它能够处理国际文件名。我在使用 Java 1.5 的 Mac 上工作,如果文件名包含需要代理的 Unicode 字符,则 JVM 似乎无法找到该文件。例如,我的测试文件是:

"草鷗外.gif"它被分解成 Java 字符\u8349\uD85B\uDFF6\u9DD7\u5916.gif

如果我从这个文件名创建一个文件,我无法打开它,因为我得到一个 FileNotFound 异常。即使在包含该文件的文件夹上使用它也会失败:

File[] files = folder.listFiles(); 
for (File file : files) {
    if (!file.exists()) {
        System.out.println("Failed to find File"); //Fails on the surrogate filename
    }
}

我实际处理的大部分代码都是以下形式:

FileInputStream instream = new FileInputStream(new File("草鷗外.gif"));
// operations follow

有什么方法可以解决这个问题,要么转义文件名,要么以不同的方式打开文件?

4

4 回答 4

7

我怀疑 Java 或 Mac 之一正在使用CESU-8而不是正确的 UTF-8。Java 使用“修改后的 UTF-8”(这是 CESU-8 的轻微变体)用于各种内部目的,但我不知道它可以将其用作文件系统/defaultCharset。不幸的是,我这里既没有 Mac 也没有 Java 可供测试。

“修改”是“严重窃听”的修改方式。而不是为像

于 2009-10-09T20:31:24.747 回答
5

如果您的环境的默认语言环境不包含这些字符,您将无法打开该文件。

请参阅:File.exists() 失败,名称中包含 unicode 字符

编辑: 好的..您需要更改系统区域设置。无论您使用什么操作系统。

编辑

请参阅:如何在 Java 中打开包含重音符号的文件?

请参阅:Mac 上的 JFileChooser 看不到以中文字符命名的文件?

于 2009-10-09T19:35:00.913 回答
3

事实证明这是 Mac JVM 的问题(在 1.5 和 1.6 上测试)。Java File 类不能访问包含补充字符/代理对的文件名。我最终为项目的 Mac 版本 (ick) 编写了一个带有 Carbon 调用的 JNI 库。我怀疑提到的 CESU-8 问题 bobince,因为获取 UTF-8 字符的 JNI 调用返回了 CESU-8 字符串。看起来这不是你可以真正解决的问题。

于 2009-11-25T21:05:17.420 回答
0

这是 old-skool java File api 中的一个错误,可能只是在 mac 上?无论如何,新的 java.nio api 工作得更好。我有几个文件包含无法使用 java.io.File 和相关类加载的 unicode 字符和内容。在将我的所有代码转换为使用java.nio.Path之后,一切都开始工作了。我用java.nio.Files替换了 org.apache.commons.io.FileUtils (有同样的问题) ......

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

于 2014-02-24T12:34:42.870 回答