我遇到了这个问题,并且已经有几天的搜索和解决方法尝试不成功。
我现在有一个由 jnlp/webstart 在 osx 和 windows 计算机上分发的内部 java swing 程序,除其他外,它从 WebDav 下载一些文件。
最近,在一台装有 OSX 10.8 和 Java 7 的测试机器上,带有重音字符的文件名和目录名开始被问号替换。
在 7 之前的 Java 版本的 OSX 上没有问题。
例子 :
XXXYYY_è_ABCD/
变成
XXXYY_?_ABCD/
在原始字符串上使用java.text.Normalizer (NFD, NFC, NFKD, NFKC),结果不同但仍然错误:
XXXYY_e?_ABCD/
或者
XXXYYY_e_ABCD/
我知道,根据 [andrew.brygin at oracle.com] 和 [mik3hall at gmail.com] 之间的通信,
是的,file.encoding 是根据运行 jvm 的语言环境设置的,如果你在 xxxx.UTF-8 语言环境中运行你的 java vm,file.encoding 应该是 UTF-8,设置为 MacRoman 会有问题。所以我相信 Oracle/OpenJDK7 的行为是正确的。也就是说,正如 Andrew Thompson 指出的那样,如果所有以前的 Apple JDK 版本都使用 MacRoman 作为英语/UTF-8 语言环境的 file.encoding,那么这里存在“兼容性”问题,可能值得在发行说明中添加一些内容Oracle/OpenJDK MacOS 用户请注意。
从Joni Salonen博客(java-and-file-names-with-invalid-characters)我知道:
您可能知道 Java 使用“默认字符编码”将二进制数据转换为字符串。要使用其他编码读取或写入文本,您可以使用 InputStreamReader 或 OutputStreamWriter。但是对于 API 深处的数据到文本的转换,您别无选择,只能更改默认编码。
和
file.encoding 呢?
file.encoding 系统属性还可用于设置 Java 用于 I/O 的默认字符编码。不幸的是,它似乎对如何将文件名解码为字符串没有影响。
从 jnlp 内部执行语言环境不变地打印
LANG=
LC_COLLATE="C"
LC_CTYPE="C"
LC_MESSAGES="C"
LC_MONETARY="C"
LC_NUMERIC="C"
LC_TIME="C"
LC_ALL=
stackoverflow 上最类似的问题是这样的: encoding-issues-on-java-7-file-names-in-os-x
但解决方案是将java程序的执行包装在一个脚本中
#!/bin/bash
export LC_CTYPE="UTF-8" # Try other options if this doesn't work
exec java your.program.Here
但我不认为这个选项对我来说是可用的,因为 webstart,我还没有找到任何方法来从程序中设置 LC_CTYPE 环境变量。
任何解决方案或解决方法?
PS:
如果我们直接从 shell 运行程序,它即使在 OSX 10+Java 7 上也能正确写入文件/目录。只有 JNLP+OSX+Java7 的组合才会出现问题