我需要使用UTF-8在我的资源属性使用Java的ResourceBundle。当我直接在属性文件中输入文本时,它显示为mojibake。

我的应用程序运行在谷歌应用程序引擎。

谁能给我举个例子?我找不到这份工作。


当前回答

Properties prop = new Properties();
String fileName = "./src/test/resources/predefined.properties";
FileInputStream inputStream = new FileInputStream(fileName);
InputStreamReader reader = new InputStreamReader(inputStream,"UTF-8");

其他回答

http://sourceforge.net/projects/eclipse-rbe/

如前所述,属性文件应该用ISO 8859-1编码

您可以使用上面的eclipse IDE插件为您进行Unicode转换。

Java 9及更新版本

从Java 9开始,属性文件默认编码为UTF-8,使用ISO-8859-1以外的字符应该可以开箱即用。

Java 8及以上版本

当指定了.properties文件时,ResourceBundle#getBundle()在封面下使用PropertyResourceBundle。这反过来使用默认的Properties#load(InputStream)来加载这些属性文件。根据javadoc,它们默认读取为ISO-8859-1。

public void load(InputStream stream)抛出IOException

从输入字节流中读取属性列表(键和元素对)。输入流采用load(Reader)中指定的简单的面向行的格式,并假定使用ISO 8859-1字符编码;即每个字节是一个拉丁字符。非拉丁字符1和某些特殊字符使用Java™语言规范3.3节中定义的Unicode转义符在键和元素中表示。

So, you'd need to save them as ISO-8859-1. If you have any characters beyond ISO-8859-1 range and you can't use \uXXXX off top of head and you're thus forced to save the file as UTF-8, then you'd need to use the native2ascii tool to convert an UTF-8 saved properties file to an ISO-8859-1 saved properties file wherein all uncovered characters are converted into \uXXXX format. The below example converts a UTF-8 encoded properties file text_utf8.properties to a valid ISO-8859-1 encoded properties file text.properties.

native2ascii -encoding UTF-8 text_utf8.properties text.properties

在使用Eclipse等正常的IDE时,当您在基于Java的项目中创建.properties文件并使用Eclipse自己的编辑器时,这已经自动完成了。Eclipse将透明地将超出ISO-8859-1范围的字符转换为\uXXXX格式。另见下面的截图(注意底部的“属性”和“源”选项卡,点击放大):

或者,您也可以创建一个定制的ResourceBundle。控件实现,其中您显式读取属性文件为UTF-8使用InputStreamReader,这样您就可以将它们保存为UTF-8而不需要与native2ascii的麻烦。下面是一个开始的例子:

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());

参见:

Unicode -如何得到正确的字符?

Properties prop = new Properties();
String fileName = "./src/test/resources/predefined.properties";
FileInputStream inputStream = new FileInputStream(fileName);
InputStreamReader reader = new InputStreamReader(inputStream,"UTF-8");

我尝试使用Rod提供的方法,但考虑到BalusC关注的是不要在所有应用程序中重复相同的工作,并附带了这个类:

import java.io.UnsupportedEncodingException;
import java.util.Locale;
import java.util.ResourceBundle;

public class MyResourceBundle {

    // feature variables
    private ResourceBundle bundle;
    private String fileEncoding;

    public MyResourceBundle(Locale locale, String fileEncoding){
        this.bundle = ResourceBundle.getBundle("com.app.Bundle", locale);
        this.fileEncoding = fileEncoding;
    }

    public MyResourceBundle(Locale locale){
        this(locale, "UTF-8");
    }

    public String getString(String key){
        String value = bundle.getString(key); 
        try {
            return new String(value.getBytes("ISO-8859-1"), fileEncoding);
        } catch (UnsupportedEncodingException e) {
            return value;
        }
    }
}

使用它的方式与常规的ResourceBundle使用非常相似:

private MyResourceBundle labels = new MyResourceBundle("es", "UTF-8");
String label = labels.getString(key)

或者你可以使用默认使用UTF-8的替代构造函数:

private MyResourceBundle labels = new MyResourceBundle("es");

看这个:http://docs.oracle.com/javase/6/docs/api/java/util/Properties.html#load(java.io.Reader)

属性接受Reader对象作为参数,您可以从InputStream创建该对象。

在创建时,你可以指定Reader的编码:

InputStreamReader isr = new InputStreamReader(stream, "UTF-8");

然后将这个Reader应用到load方法:

prop.load(isr);

顺便说一句:从.properties文件中获取流:

 InputStream stream = this.class.getClassLoader().getResourceAsStream("a.properties");

顺便说一句:从InputStreamReader获取资源包:

ResourceBundle rb = new PropertyResourceBundle(isr);

希望这能帮助到你!