3

我有一个问题,我无法在 Solaris 上的文件名中写入带有重音符号的文件。

给出以下代码

public static void main(String[] args) {
    System.out.println("Charset = "+ Charset.defaultCharset().toString());
    System.out.println("testéörtkuoë");
    FileWriter fw = null;
    try {
        fw  = new FileWriter("testéörtkuoë");
        fw.write("testéörtkuoëéörtkuoë");
        fw.close();

我得到以下输出

Charset = ISO-8859-1
test??rtkuo?

我得到一个名为“test??rtkuo?”的文件

根据我在 StackOverflow 上找到的信息,我尝试通过在启动时添加“-Dfile.encoding=UTF-8”来调用 Java 应用程序。这将返回以下输出

Charset = UTF-8
testéörtkuoë

但文件名仍然是“test??rtkuo?”

任何帮助深表感谢。

史蒂夫

4

5 回答 5

4

所有这些字符都存在于ISO-8859-1中。我怀疑问题的一部分是代码编辑器正在以与您的操作系统正在使用的不同编码保存文件。

如果编辑器使用 ISO-8859-1,我希望它将 ëéö 编码为:

eb e9 f6

如果编辑器使用 UTF-8,我希望它将 ëéö 编码为:

c3ab c3a9 c3b6

其他编码会产生不同的值。

如果您使用Unicode 转义序列,源文件会更便于移植。至少要确定您的编译器使用与编辑器相同的编码。

例子:

ë    \u00EB
é    \u00E9
ö    \u00F6

您可以使用Unicode 图表查找这些值。

使用 -Dfile.encoding=UTF-8 更改默认文件编码可能会对 JVM 与系统的交互方式产生意想不到的后果。

这与您可能在 Windows 上看到的问题有相似之处。

我无法直接重现该问题 - 我的 OpenSolaris 版本使用 UTF-8 作为默认编码。

于 2009-04-21T16:00:45.797 回答
1

如果您尝试使用 java io api 列出文件名,您会看到什么?它们的编码是否正确?我很好奇真正的问题是编码文件名还是使用您用来检查它们的工具。

于 2009-04-21T15:10:24.543 回答
0

当你这样做时会发生什么:

ls > testéörtkuoë

如果这有效(正确写入文件),那么您知道您可以写入带有重音符号的文件。

于 2009-04-21T15:46:46.687 回答
0

Java 在读写文件时使用操作系统的默认编码。现在,一个人永远不应该依赖它。明确指定编码始终是一个好习惯。

在 Java 中,您可以使用以下内容进行读写:

阅读:

BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(inputPath),"UTF-8"));

写作:

PrintWriter pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outputPath), "UTF-8")));
于 2010-05-24T06:02:42.747 回答
0

我遇到了类似的问题。与该示例相反,程序无法使用 列出正确的文件sysout.println,尽管ls显示了正确的值。

如文档中所述,环境变量file.encoding不应用于定义字符集,在这种情况下,JVM 会忽略它

症状:

  1. 我无法在 shell 中输入重音符号。
  2. ls显示正确的值
  3. File.list()正在打印不正确的值
  4. 环境file.encoding不影响输出
  5. 环境user.(language|country)不影响输出

解决方案:

尽管环境变量LC_*在 shell 中设置为从 /etc/defaut/init 继承的值,如set命令所列,但语言环境显示不同的值。

$ set | grep LC
LC_ALL=pt_BR.ISO8859-1
LC_COLLATE=pt_BR.ISO8859-1
LC_CTYPE=pt_BR.ISO8859-1
LC_MESSAGES=C
LC_MONETARY=pt_BR.ISO8859-1
LC_NUMERIC=pt_BR.ISO8859-1
LC_TIME=pt_BR.ISO8859-1

$ locale
LANG=
LC_CTYPE="C"
LC_NUMERIC="C"
LC_TIME="C"
LC_COLLATE="C"
LC_MONETARY="C"
LC_MESSAGES="C"
LC_ALL=

解决方案是简单地导出 LANG。这个环境变量真的影响jvm

LANG=pt_BR.ISO8859-1
export LANG
于 2010-05-19T21:51:56.150 回答