使用UTF-8的getBytes()不适用于大写德语变音符号

sjn*_*ngm 5 java resourcebundle character-encoding

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

menu.file.open.label=&Öffnen...
label.btn.add.name=&Hinzufügen
label.btn.remove.name=&Löschen
Run Code Online (Sandbox Code Playgroud)

由于这会在使用非ASCII字符时导致字符编码问题,我以为我会满意:

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

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

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

&Ã?ber => &??ber
&SchlieÃ?en => &Schlie??en
&Ã?ffnen... => &??ffnen...
Run Code Online (Sandbox Code Playgroud)

最后三个应该是:

&Ã?ber => &Über
&SchlieÃ?en => &Schließen
&Ã?ffnen... => &Öffnen...
Run Code Online (Sandbox Code Playgroud)

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

谷歌发现了类似的东西,但仍然没有答案.

编辑:多一点代码

Jon*_*eet 6

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

如果你在两个方向都使用UTF-8,那就没关系了:

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

...但是如果您尝试使用它来读取UTF-8编码的属性文件而不告诉正在执行初始读取的代码,则无效.

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

准确告诉我们您遇到的问题ResourceBundle,我们可以看看是否可以找到根本原因.

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

native2ascii -encoding UTF-8 input.properties output.properties
Run Code Online (Sandbox Code Playgroud)


sjn*_*ngm 0

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

\n\n
    \n
  1. 创建 Ant 风格的 build.xml

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

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

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

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

\n\n

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

\n