6

对于开发,我ResourceBundle用来直接从 IDE 中的资源目录中读取 UTF-8 编码的属性文件(我在该文件的 Eclipse 文件属性中设置)(native2ascii 用于生产方式),例如:

menu.file.open.label=&Öffnen...
label.btn.add.name=&Hinzufügen
label.btn.remove.name=&Löschen

由于在使用非 ASCII 字符时会导致字符编码出现问题,我认为我会很高兴:

ResourceBundle resourceBundle = ResourceBundle.getBundle("messages", Locale.getDefault());
String value = resourceBundle.getString(key);
value = new String(value.getBytes(), "UTF-8");

好吧,它确实适用于小写的德语变音符号,但不适用于大写的变音符号,ß也不起作用。这是读取getString(key)的值和转换后的值new String(value.getBytes(), "UTF-8")

&Löschen => &Löschen
&Hinzufügen => &Hinzufügen

&Ã?ber => &??ber
&SchlieÃ?en => &Schlie??en
&Ã?ffnen... => &??ffnen...

最后三个应该是:

&Ã?ber => &Über
&SchlieÃ?en => &Schließen
&Ã?ffnen... => &Öffnen...

我想我离真相并不太远,但我在这里错过了什么?

谷歌发现了类似的东西,但仍未得到答复。

编辑:更多代码

4

4 回答 4

6

问题是您在String.getBytes() 没有指定编码的情况下调用 - 这将使用默认平台编码。然后,您可以像使用UTF-8一样使用该操作的二进制结果。

如果您在两个方向上都使用 UTF-8,那就没问题了:

// Should be a round-trip
value = new String(value.getBytes("UTF-8"), "UTF-8");

...但是如果您尝试使用它来读取 UTF-8 编码的属性文件而不告诉执行初始读取的代码,那将无法正常工作。

您提供的代码基本上总是错误的方法。您的“因为这会导致字符编码出现问题”表明您已经遇到了较早的问题 - 所以我会回到那个问题,而不是尝试应用损坏的修复程序。如果您在构建时已经丢失了数据ResourceBundle,那么以后再回去就太晚了……您需要确保ResourceBundle自己正确加载。

请准确告诉我们您使用ResourceBundle.

编辑:目前尚不清楚您是如何运行 native2ascii 的。修复可能就像更改为使用一样简单:

native2ascii -encoding UTF-8 input.properties output.properties
于 2012-09-03T19:56:49.767 回答
3

一些注意事项:

  • 如果是String,则为 UTF-16,如果不是,则为损坏的字符串(修复为时已晚。)
  • new String(value.getBytes(), "UTF-8");- 此代码(充其量)在使用 UTF-8 作为默认编码的系统上什么也不做;否则会损坏字符串。
  • .properties 文件必须是 ISO 8859-1 (该Properties类型支持其他格式和编码,但我不知道你会怎么看ResourceBundle。)
  • System.out可能会引入自己的转码错误(PrintStream将 UTF-16 字符串编码为默认编码;接收设备必须使用相同的编码解码字节。)

我怀疑你试图在错误的地方解决你的问题。

于 2012-09-03T20:26:13.393 回答
2

您正在使用与您正在解码的编码不同的编码对文本进行编码。

尝试使用相同的字符集进行编码和解码。

value = new String(value.getBytes("UTF-8"), "UTF-8");

String s = "ßßßßß";
s += s.toUpperCase();
s = new String(s.getBytes("UTF-8"), "UTF-8");
System.out.println(s);

印刷

ßßßßßSSSSSSSSSS
于 2012-09-03T19:57:46.633 回答
0

今天我正在和我的一位同事交谈,他与其他答案提到的几乎相同。所以我试图实现 Jon Skeet 提到的,这意味着创建与生产中相同的文件。由于在每次更改资源后重建项目是不可能的,而且我还没有做任何解决这个问题的方法(我想这对某些人来说是新的)让我把它排成一行(即使它可能只是为了个人参考 ;) )。简而言之,这使用了 Eclipse 的项目构建器。

  1. 创建一个 Ant 风格的 build.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <project>
        <property name="dir.resources" value="src/main/resources" />
        <property name="dir.target" value="bin/main" />
    
        <target name="native-to-ascii">
            <delete dir="${dir.target}" includes="**/*.properties" />
            <native2ascii src="${dir.resources}" dest="${dir.target}" includes="**/*.properties" />
        </target>
    </project>
    

    其目的是删除目标目录中的属性文件并用于native2ascii重新创建它们。删除是必要的,因为native2ascii不会覆盖现有文件。

  2. 在 Eclipse 中,转到项目属性并选择“Builders”,单击“New...”,选择“Ant Builder”(这是运行配置的略微增强的编辑器)
  3. 在“Main”中让“Buildfile”指向 Ant 脚本,将“Base Directory”设置为${project_loc}
  4. 在“刷新”中勾选“完成后刷新资源”并选择“包含所选资源的项目”
  5. 在“目标”中,单击“自动构建”旁边的“设置目标”并选择native-to-ascii那里(请注意,由于某种原因,我必须稍后再执行此操作)
  6. 这可能不是每个人都需要的,但是在“JRE”中选择一个合适的执行环境
  7. 在“构建选项”中勾选“分配控制台”(但是,您可能希望保持勾选,直到您看到一切正常)
  8. “应用”、“确定”
  9. 有人告诉我,新创建的构建器应该位于 Java Builder 下方(使用向上/向下按钮)
  10. 在“Java Build Path”中选择包含资源的源文件夹(src/main/resources对我来说)并添加排除项**/*.properties

应该是这样的。如果您编辑属性文件并保存它,它应该会在输出文件夹中自动转换为 ASCII。您可以尝试输入ü,它应该以\u00fc.

请注意,如果您有很多属性文件,这可能需要一些时间。只是不要在每次按键后保存。:)

于 2012-09-04T17:13:55.490 回答