为啥资源包中的瑞典语文本显示为乱码? [复制]

Posted

技术标签:

【中文标题】为啥资源包中的瑞典语文本显示为乱码? [复制]【英文标题】:Why is text in Swedish from a resource bundle showing up as gibberish? [duplicate]为什么资源包中的瑞典语文本显示为乱码? [复制] 【发布时间】:2011-05-24 15:25:22 【问题描述】:

可能重复:How to use UTF-8 in resource properties with ResourceBundle

我想允许我的 Java Swing 应用程序国际化。我使用捆绑文件将所有标签保存在其中。

作为测试,我尝试将瑞典语标题设置为 JButton。所以在我写的包文件中:

nextStepButton=nästa

在我写的Java代码中:

nextStepButton.setText(bundle.getString("nextStepButton"));

但按钮的标题字符在运行时出现错误:

我正在使用支持 Unicode 的 Tahoma 字体。 当我通过代码手动设置按钮标题时,它看起来很好:

nextStepButton.setText("nästa");

知道为什么它在捆绑文件中失败了吗?

------------------------------> 编辑:对标题进行编码: 我尝试使用以下代码对来自捆绑文件的文本进行编码:

nextStepButton.setText(new String(bundle.getString("nextStepButton").getBytes("UTF-8")));

结果仍然是:

【问题讨论】:

也许你的捆绑文件编码不正确? 如何创建属性文件? 我使用 Eclipse ...我从 Eclipse 内部创建属性文件作为普通文本文件 + 我将其编码设置为“UTF-8”。 【参考方案1】:

根据javadoc,使用 ISO-8859-1 读取属性文件。

.. 输入/输出流以 ISO 8859-1 字符编码进行编码。不能用这种编码直接表示的字符可以使用 Unicode 转义来编写;转义序列中只允许使用单个 'u' 字符。 native2ascii 工具可用于将属性文件与其他字符编码进行转换。

除了使用 native2ascii 工具将 UTF-8 属性文件转换为 ISO-8859-1 属性文件外,您还可以使用自定义的ResourceBundle.Control 以便您可以控制属性文件的加载并在那里使用 UTF-8 .这是一个启动示例:

public class UTF8Control extends Control 
    public ResourceBundle newBundle
        (String baseName, Locale locale, String format, ClassLoader loader, boolean reload)
            throws IllegalAccessException, InstantiationException, IOException
    
        // The below is a copy of the default implementation.
        String bundleName = toBundleName(baseName, locale);
        String resourceName = toResourceName(bundleName, "properties");
        ResourceBundle bundle = null;
        InputStream stream = null;
        if (reload) 
            URL url = loader.getResource(resourceName);
            if (url != null) 
                URLConnection connection = url.openConnection();
                if (connection != null) 
                    connection.setUseCaches(false);
                    stream = connection.getInputStream();
                
            
         else 
            stream = loader.getResourceAsStream(resourceName);
        
        if (stream != null) 
            try 
                // Only this line is changed to make it to read properties files as UTF-8.
                bundle = new PropertyResourceBundle(new InputStreamReader(stream, "UTF-8"));
             finally 
                stream.close();
            
        
        return bundle;
    

如下使用:

ResourceBundle bundle = ResourceBundle.getBundle("com.example.i18n.text", new UTF8Control());

这样您就无需麻烦地使用 native2ascii 工具,并且最终获得更好的可维护属性文件。

另见:

Unicode - How to get the characters right?

【讨论】:

我花了一些时间来理解和测试这个......它真的很好......现在是I18N。 不客气。究竟哪一部分难以理解?我可以编辑答案以使其更清楚。 在我的情况下&根据你的回答......从 UTF8Control 初始化一个对象将是: ResourceBundle bundle = ResourceBundle.getBundle( "swedish", new UTF8Control() );【参考方案2】:

看看Java Internationalization FAQ。如果您在 .properties 文件中放入了非 ASCII 字符,则必须使用 native2ascii 工具对其进行转换。那么一切都应该正常。

【讨论】:

【参考方案3】:

问题是资源包属性文件以 UTF-8 编码,但您的应用程序正在使用 Latin-1 加载它。

如果您采用“LATIN SMALL A WITH DIAERESIS”(Latin-1 中的 E4 或 0000E4 作为 Unicode 代码点)并将其表示为 UTF-8,您将得到 C3 A4。如果您随后将它们视为 Latin-1 字节,您会得到“LATIN CAPITAL LETTER A WITH TILDE”和方形“CURRENCY SIGN”字符......这就是字符在按钮屏幕截图中的显示方式!!

(顺便说一句,这是一个新词,用于表示由于使用错误的字符编码而导致的混乱……mojibake。在对话中使用它来迷惑你的朋友。)

【讨论】:

以上是关于为啥资源包中的瑞典语文本显示为乱码? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

使用 NSBundle 加载我的资源

当我将 print_r() 应用于 PHP 中的数组时,为啥会得到“资源 id #4”? [复制]

有没有办法在 Eclipse 中搜索包中的文本?

如何从 android 包中的资源 id 获取 Drawable 对象?

使用 FHIR nuget 包通过引用查找包中的资源

Xcode iOS Build - 仅将特定子文件夹复制为捆绑资源