【问题标题】:Generate a Properties object from a ResourceBundle?从 ResourceBundle 生成一个 Properties 对象?
【发布时间】:2011-07-06 20:31:35
【问题描述】:

我有一个基于.properties 文件堆栈的“普通”Java PropertyResourceBundle。在某些地方,基于正确翻译的.properties 文件而不是ResourceBundleProperties 对象进行操作会更方便。有没有一种方便的方式将ResourceBundle“转换”为Properties

我想要的是这样的:

Locale currentLocale = MagicLocaleFactory.getLocale();
ResourceBundle myResources = ResourceBundle.getBundle("MyResources", currentLocale);

Properties myProperties = myResources.magicallyProduceAPropertiesObject();

因此,myProperties 对象的行为就好像它是从 ResourceBundle.getBundle() 找到的同一个 .properties 文件中实例化的一样。

有几种方法可以“手动”执行此操作;例如,迭代 ResourceBundle 的一组键值对并将它们安装在新的 Properties 对象中,但我希望有更好的,或者至少更短的方法来做到这一点。

编辑:

回答显而易见的“但是,为什么?”问题是这样的:我们正在为 i18n 改造一个长期存在的桌面 Java 程序。该程序已经从由单个.properties 文件支持的Properties 对象中提取字符串。我们用多个文件替换单个文件并将Properties 对象“提升”为资源包。问题在于,在Properties 上获取密钥的方法是getProperty,而对于ResourceBundle,它是getStringgetObject。在Properties 对象在程序中传递并拉出字符串之前更改它的来源非常容易。更改实际的方法调用...不太容易。当然,您几乎可以搜索和替换它,但是我们不能只更改加载属性的一个类,本质上我们必须触及每个源文件。 (是的,这个东西有很多文字。)我们希望我们错过了一种使用ResourceBundle 的多个.properties 和回退机制而无需重新连接整个应用程序的方法。 (无端的甘道夫引用:“从来没有太多希望。只是一个傻瓜的希望。”)

【问题讨论】:

    标签: java internationalization resourcebundle


    【解决方案1】:

    没有内置的方法可以做你想做的事,但正如你所说,自己做并不难:基本上具有相同的界面,并将键和值从包复制到属性很简单。

    不过,有一个警告。尽管接口相似,但实现却不同:资源包有一个继承模型,如果foo_fr_FR.propertiesfoo_fr.properties 中未定义该值,则该模型允许返回foo.properties 中的值。因此,复制所有条目不会得到与从属性文件加载的相同的属性。它将获取属性文件的条目及其所有父项的属性。但我猜你知道这一点,因为你说的是​​一堆属性文件。

    你没有说明为什么你更喜欢属性而不是 ResourceBundle,所以很难给你一个更好的答案。

    另一种解决方案是自己加载属性:

    Properties props = new Properties();
    properties.load(MyClass.class.getResourceAsStream("MyResources_" + locale + ".properties")
    

    这样,您将只从特定属性文件中获取条目。

    【讨论】:

      【解决方案2】:

      没有,并且有充分的理由:ResourceBundle 旨在包含不同语言的属性,因此它会加载 * 并回退 适当的文件 - 当你要求让我们说消息时de-AT 语言环境(德语、奥地利),如果它能够找到一个,它将回退到德语,或者在其他情况下回退到您的基本属性文件 (messages.properties)。

      我真的不知道您在这里的用例是什么(也许它可以通过不同的方式实现?)但似乎唯一的方法是直接从属性文件中读取,不幸的是模仿了我上面提到的机制(棘手的部分是巴西葡萄牙语和繁体中文,它们不应回退到它们的“默认”语言(分别为“pt”和“zh”)。

      【讨论】:

        【解决方案3】:

        另一种解决方案是迭代键并将所有对放在一个属性对象中,您可以使用convertBundleToProperties

        static Properties convertBundleToProperties(ResourceBundle resource) {
            Properties properties = new Properties();
        
            Enumeration<String> keys = resource.getKeys();
            while (keys.hasMoreElements()) {
              String key = keys.nextElement();
              properties.put(key, resource.getString(key));
            }
        
            return properties;
         }
        

        【讨论】:

          猜你喜欢
          • 2013-01-06
          • 2011-12-21
          • 1970-01-01
          • 1970-01-01
          • 2021-04-21
          • 2021-11-03
          • 2017-10-26
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多