【问题标题】:Encoding of file names in JavaJava中文件名的编码
【发布时间】:2012-04-23 18:30:29
【问题描述】:

我正在嵌入式 Linux 平台上运行一个小型 Java 应用程序。将 Java VM JamVM 替换为 OpenJDK 后,带有特殊字符的文件名无法正确存储。变音符号等特殊字符被问号替换。

这是我的测试代码:

import java.io.File;
import java.io.IOException;

public class FilenameEncoding
{

        public static void main (String[] args) {
                String name = "umlaute-äöü";
                System.out.println("\nname = " + name);
                System.out.print("name in Bytes: ");
                for (byte b : name.getBytes()) {
                        System.out.print(Integer.toHexString(b & 255) + " ");
                }
                System.out.println();

                try {
                        File f = new File(name);
                        f.createNewFile();
                } catch (IOException e) {
                        e.printStackTrace();
                }
        }

}

运行它会给出以下输出:

name = umlaute-???
name in Bytes: 75 6d 6c 61 75 74 65 2d 3f 3f 3f

还有一个叫做变音符号的文件-???已创建。

将属性 file.encoding 和 sun.jnu.encoding 设置为 UTF-8 会在终端中提供正确的字符串,但创建的文件仍然是变音符号-???

用strace运行虚拟机,可以看到系统调用

open("umlaute-???", O_RDWR|O_CREAT|O_EXCL|O_LARGEFILE, 0666) = 4

这表明问题不是文件系统问题,而是虚拟机之一。

文件名的编码如何设置?

【问题讨论】:

  • 请浏览解释设置编码的链接。stackoverflow.com/questions/361975/…
  • 设置 file.encoding 没有帮助。它只影响文件内容,不影响文件名。
  • 这可能对您有所帮助.. stackoverflow.com/questions/1184176/…
  • 你检查过底层文件系统甚至支持 UTF-8 吗?
  • 我敢肯定,这不是文件系统问题。我可以在命令行上创建这些文件。此外,另一个虚拟机 JamVM 可以正确创建和处理此类文件。 strace 显示,对 open() 的调用已经包含问号,而不是 ä、ö 和 ü。

标签: java encoding jvm openjdk


【解决方案1】:

如果您使用的是 Eclipse,那么您可以转到 Window->Preferences->General->Workspace 并从下拉菜单中选择您想要的“文本文件编码”选项。通过更改我的问题,我能够重现您的问题(并且还改回修复程序)。

如果你不是,那么你可以添加一个环境变量到windows(系统属性->环境变量和系统变量下你想选择新建...)名称应该是(不带引号)JAVA_TOOL_OPTIONS和值应该设置为-Dfile.encoding=UTF8(或者任何可以让你工作的编码。

我通过这篇文章找到了答案,顺便说一句: Setting the default Java character encoding?

Linux 解决方案

-(Permanent) 在终端中使用env | grep LANG 会给你一个或两个关于linux当前设置的编码的回复。然后,您可以在 /etc/sysconfig i18n 文件中将 LANG 设置为 UTF8(您的可能设置为 ASCII)(我在 2.6.40 fedora 上对此进行了测试)。基本上,我从 UTF8(我有奇数字符)切换到 ASCII(我有问号)并返回。

-(在运行 JVM,但可能无法解决问题)您可以使用 java -Dfile.encoding=**** FilenameEncoding 以您想要的编码启动 JVM 以下是两种方式的输出:

[youssef@JoeLaptop bin]$ java -Dfile.encoding=UTF8 FilenameEncoding

name = umlaute-הצ�
name in Bytes: 75 6d 6c 61 75 74 65 2d d7 94 d7 a6 ef bf bd 
UTF-8
UTF8

[youssef@JoeLaptop bin]$ java FilenameEncoding

name = umlaute-???????
name in Bytes: 75 6d 6c 61 75 74 65 2d 3f 3f 3f 3f 3f 3f 3f 
US-ASCII
ASCII

这里是一些关于 linux 的参考资料 http://www.cyberciti.biz/faq/set-environment-variable-linux/

这里是关于 -Dfile.encoding Setting the default Java character encoding?

【讨论】:

  • 我在编译的.class-File中检查了文件名的编码。那里是正确的。相同的 .class-File 适用于桌面 linux,但不适用于嵌入式。
  • 你能提供更多关于你正在使用的 Linux 的信息吗?思路是一样的,只需要适应启动JVM的程序/OS即可。
  • 它是在 ARM v5 处理器 (Atmel AT91SAM9G20) 上运行的内核 2.6.30。一个有趣的事实是 JamVM 可以处理这样的文件名,但 OpenJDK 不能。 OpenJDK 依赖于哪些 OS 特性?
  • 更新了我的答案!希望有帮助。您也可以使用输入和输出流,但我认为您的问题是 Linux 设置的 LANG 不支持您的字符。如果我在正确的 LANG btw 中,我只能让我的文件正确写入。否则我不会得到??? (虽然终端显示???),但我会得到这个:×צ�
【解决方案2】:

我知道这是一个老问题,但我遇到了同样的问题。 所有提到的解决方案都对我不起作用,但以下解决了它:

  • UTF8 的源编码(maven 属性中的 project.build.sourceEncoding 为 UTF-8)
  • 程序参数:-Dfile.encoding=utf8 和 -Dsun.jnu.encoding=utf8
  • 使用 java.nio.file.Path 代替 java.io.File

【讨论】:

    【解决方案3】:

    您的问题是 javac 期望您的 .java 文件的编码与您保存的不同。编译时javac没有警告过你吗?

    也许您已经使用编码ISO-8859-1windows-1252 保存了它,而javac 期待UTF-8

    使用-encoding 标志为javac 提供正确的编码,或为您的构建工具提供等效的编码。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-09-12
      • 1970-01-01
      • 2013-01-30
      • 2012-06-12
      • 2010-11-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多