【问题标题】:Java properties UTF-8 encoding in EclipseEclipse 中的 Java 属性 UTF-8 编码
【发布时间】:2010-10-26 05:13:02
【问题描述】:

我最近不得不将我正在开发的 webapp 的编码从 ISO-xx 切换到 utf8。一切都很顺利,除了属性文件。我在eclipse.ini 中添加了-Dfile.encoding=UTF-8,普通文件工作正常。然而,属性显示出一些奇怪的行为。

如果我从 Notepad++ 复制 utf8 编码属性并将它们粘贴到 Eclipse 中,它们会显示并正常工作。当我重新打开属性文件时,我看到一些 Unicode 字符而不是正确的字符,例如:

Zur\u00EF\u00BF\u00BDck instead of Zurück

但应用程序仍然可以正常工作。 如果我开始编辑属性,添加一些特殊字符并保存,它们会正确显示,但是它们不起作用,并且所有以前工作的特殊字符都不再起作用。

当我将本地版本与 CVS 进行比较时,我可以在远程文件上正确地看到特殊字符,并且在更新后我又开始了:应用程序工作正常,但 Eclipse 显示 Unicode 字符。

我尝试通过右键单击它并选择“其他:UTF8”来更改文件编码,但它没有帮助。它还说:“由内容决定:ISO-8859-1”

我正在使用基于 Eclipse 3.3 的 Java 6 和 Jboss Developer

我可以通过在 Notepad++ 中编辑属性并将它们粘贴到 Eclipse 中来忍受它,但如果有人可以帮助我在 Eclipse 中修复这个问题,我将不胜感激。

【问题讨论】:

    标签: java eclipse encoding utf-8


    【解决方案1】:

    “pre-Java-9”的答案如下。从 Java 9 开始,属性文件默认以 UTF-8 保存和加载,但如果检测到无效的 UTF-8 字节序列,则会回退到 ISO-8859-1。详情请见Java 9 release notes


    根据定义,属性文件是 ISO-8859-1 - 请参阅Properties 类的文档。

    Spring 有一个替代品,可以使用PropertiesFactoryBean 加载指定的编码。

    编辑:正如 Laurence 在 cmets 中指出的那样,Java 1.6 引入了 loadstore 的重载,它们采用 Reader/Writer。这意味着您可以使用您想要的任何编码为文件创建一个阅读器,并将其传递给load。不幸的是,FileReader 仍然 不允许您在构造函数 (aargh) 中指定编码,因此您将无法将 FileInputStreamInputStreamReader 链接在一起。但是,它会起作用。

    例如,使用 UTF-8 读取文件:

    Properties properties = new Properties();
    InputStream inputStream = new FileInputStream("path/to/file");
    try {
        Reader reader = new InputStreamReader(inputStream, "UTF-8");
        try {
            properties.load(reader);
        } finally {
            reader.close();
        }
    } finally {
       inputStream.close();
    }
    

    【讨论】:

    • 在 Java 1.6 中,您可以通过使用 Reader/Writer 而不是 InputStream/OutputStream 的方法来使用其他编码。
    • 比公认答案中的解决方案更通用,因此更好:)
    • @JonSkeet 我已经研究这个问题好几个星期了。非常感谢!
    • 从 Java 9+ 开始,属性文件应使用 UTF-8 编码:docs.oracle.com/javase/9/intl/…
    • @RuneAamodt:虽然我很高兴看到在阅读时仍然支持 ISO-8859-1。将更新我的答案。
    【解决方案2】:

    不要浪费你的时间,你可以在Eclipse

    中使用Resource Bundle plugin

    Old Sourceforge page

    【讨论】:

    • 这是一个非常有用的插件,感谢您的提示!太糟糕了,它没有安装 URL,但只需将其放在插件文件夹中就可以了。
    • 这是在内部使用 native2ascii 工具处理非 unicode 字符还是我应该手动转义 unicode 符号?
    • @baybora.oren:我在 eclipse 文件夹插件中展开了 .zip,但在 ide 中没有看到任何变化(我关闭并重新启动 eclipse)。有什么提示吗?
    • @cricket 检查 eclipse 版本可能与您使用的 eclipse 不兼容
    【解决方案3】:

    这不是 Eclipse 的问题。如果您使用 Properties 类来读取和存储属性文件,该类将转义所有特殊字符。

    From the class documentation:

    将属性保存到流或从流加载时,使用 ISO 8859-1 字符编码。对于这种编码不能直接表示的字符,使用Unicode转义;但是,转义序列中只允许使用单个 'u' 字符。 native2ascii 工具可用于将属性文件与其他字符编码进行转换。

    From the API, store() method:

    小于 \u0020 的字符和大于 \u007E 的字符写成 \uxxxx 对应的十六进制值 xxxx。

    【讨论】:

    • NetBeans 可以很好地显示具有 \uXXXX 转义的属性文件,并允许您使用正确显示的 UTF 字符对其进行编辑。为什么没有 Eclipse?在我看来,这 Eclipse 的一个问题。
    • +1:被skeet'd带来的安慰
    【解决方案4】:
    Properties props = new Properties();
    URL resource = getClass().getClassLoader().getResource("data.properties");         
    props.load(new InputStreamReader(resource.openStream(), "UTF8"));
    

    像魅力一样工作

    :-)

    【讨论】:

    • 不幸的是,props.load 在 1.6 中需要一个 InputStream 并明确指出它需要老式的 ISO-8859-1
    【解决方案5】:

    您描述的过程中有太多可能发生错误的点,所以我不会试图猜测您做错了什么,但我想我知道幕后发生了什么。

    EF BF BDU+FFFD 的 UTF-8 编码形式,是解码器在遇到格式错误的输入时插入的标准替换字符。听起来您的文本被保存为 ISO-8859-1,然后像 UTF-8 一样读取,然后保存为 UTF-8,然后使用平台默认编码使用native2ascii 转换为属性格式(例如, windows-1252)。

    ü => 0xFC // 保存为 ISO-8859-1
    0xFC => U+FFFD // 读取为 UTF-8
    U+FFFD => 0xEF 0xBF 0xBD // 保存为 UTF-8
    0xEF 0xBF 0xBD => \u00EF\u00BF\u00BD // native2ascii

    我建议您不要理会“file.encoding”属性。像“file.separator”和“line.separator”一样,它并没有你想象的那么有用。相反,请养成在读写文本文件时始终指定编码的习惯。

    【讨论】:

      【解决方案6】:
      Properties props = new Properties();
      URL resource = getClass().getClassLoader().getResource("data.properties");         
      props.load(new InputStreamReader(resource.openStream(), "UTF8"));
      

      这在 java 1.6 中运行良好。我如何在 1.5 中做到这一点,因为 Properties 类没有解析 InputStreamReader 的方法。

      【讨论】:

        【解决方案7】:

        有更简单的方法:

        props.load(new InputStreamReader(new FileInputStream("properties_file"), "UTF8"));
        

        【讨论】:

          【解决方案8】:

          只是另一个用于 *.properties 文件的 Eclipse 插件:

          Properties Editor

          【讨论】:

            【解决方案9】:

            您可以定义 UTF-8 .properties 文件来存储您的翻译并使用 ResourceBundle 来获取值。为避免出现问题,您可以更改编码:

            String value = RESOURCE_BUNDLE.getString(key); 
            return new String(value.getBytes("ISO-8859-1"), "UTF-8");
            

            【讨论】:

              【解决方案10】:

              这似乎只适用于某些字符...包括德语、葡萄牙语、法语的特殊字符。但是,我遇到了俄语、印地语和普通话字符的问题。这些不会转换为属性格式“native2ascii”,而是使用 ?? ?? ??
              我可以让我的应用程序正确显示这些字符的唯一方法是将它们放入转换为 UTF-8 格式的属性文件中 - 作为 \u0915 而不是 क,或 \u044F 而不是 я。 有什么建议吗?

              【讨论】:

              • 您可以使用 Spring 的 org.springframework.context.support.ReloadableResourceBundleMessageSource 支持 UTF-8 编码的属性文件。我们使用 Spring 在基于 spring-mvc 的 Web 应用程序中管理英语、德语、法语和中文的翻译。
              【解决方案11】:

              我建议您使用 Attesoro (http://attesoro.org/)。简单易用。并且是用java制作的。

              【讨论】:

                【解决方案12】:

                如果属性用于 XML 或 HTML,则使用 XML 实体是最安全的。它们读起来更难看,但这意味着属性文件可以被视为直接 ASCII,所以不会有任何损坏。

                请注意,HTML 具有 XML 没有的实体,因此我使用直接 XML 来保证它的安全:http://www.w3.org/TR/html4/sgml/entities.html

                【讨论】:

                  猜你喜欢
                  • 2016-09-23
                  • 2012-01-09
                  • 2014-09-11
                  • 1970-01-01
                  • 2013-11-12
                  • 2014-06-12
                  • 2014-10-13
                  相关资源
                  最近更新 更多