是否可以在资源包中包含资源包文件

时间:2011-01-06 11:37:27

标签: java resourcebundle

我们正在使用java.util.ResourceBundle来加载属性信息。我们的属性文件变得如此庞大,我们正在考虑将主属性文件拆分为多个子模块。是否有可能实现这一目标?

master.properties

==> 

 master.properties
   include moduleA.properties
   include moduleB.properties

请告诉我?

3 个答案:

答案 0 :(得分:12)

首先,我想知道为什么你选择java.util.ResourceBundle超过java.util.Properties。鉴于您的问题是如何制定的,您似乎并不关心本地化/国际化,也不关心包文件继承。

使用Properties非常容易,因为它实现了Map,而putAll()又提供了Control方法来合并另一个地图。开球的例子:

Properties master = new Properties();
master.load(masterInput);

Properties moduleA = new Properties();
moduleA.load(moduleAinput);
master.putAll(moduleA);

Properties moduleB = new Properties();
moduleB.load(moduleBinput);
master.putAll(moduleB);

// Now `master` contains the properties of all files.

如果您真的坚持使用ResourceBundle,最好的办法是创建一个自定义ResourceBundle,其中您可以通过自定义{{3}}控制加载。

假设您在master.properties中有以下条目,该条目表示带有模块属性文件基本名称的逗号分隔字符串:

include=moduleA,moduleB

然后,以下自定义ResourceBundle示例应该有效:

public class MultiResourceBundle extends ResourceBundle {

    protected static final Control CONTROL = new MultiResourceBundleControl();
    private Properties properties;

    public MultiResourceBundle(String baseName) {
        setParent(ResourceBundle.getBundle(baseName, CONTROL));
    }

    protected MultiResourceBundle(Properties properties) {
        this.properties = properties;
    }

    @Override
    protected Object handleGetObject(String key) {
        return properties != null ? properties.get(key) : parent.getObject(key);
    }

    @Override
    @SuppressWarnings("unchecked")
    public Enumeration<String> getKeys() {
        return properties != null ? (Enumeration<String>) properties.propertyNames() : parent.getKeys();
    }

    protected static class MultiResourceBundleControl extends Control {
        @Override
        public ResourceBundle newBundle(
            String baseName, Locale locale, String format, ClassLoader loader, boolean reload)
                throws IllegalAccessException, InstantiationException, IOException
        {
            Properties properties = load(baseName, loader);
            String include = properties.getProperty("include");
            if (include != null) {
                for (String includeBaseName : include.split("\\s*,\\s*")) {
                    properties.putAll(load(includeBaseName, loader));
                }
            }
            return new MultiResourceBundle(properties);
        }

        private Properties load(String baseName, ClassLoader loader) throws IOException {
            Properties properties = new Properties();
            properties.load(loader.getResourceAsStream(baseName + ".properties"));
            return properties;
        }
    }

}

(除了琐碎的异常处理和本地化处理,这取决于您)

这可以用作:

ResourceBundle bundle = new MultiResourceBundle("master");

答案 1 :(得分:1)

但是,您可以以编程方式构建ResourceBundle,但正如您所说的文件很大,那么如果它被加载到内存中会怎样。

<强>更新

public class Resource extends java.util.ResourceBundle {



    public Object handleGetObject(String key) {
         //code
    }

    public Enumeration getKeys() {
         //code
    }
}

然后是IN语言环境

import java.util.*;

public class Resource_en_IN extends Resource{

  public Object handleGetObject(String key) {
    //code
  }
}

答案 2 :(得分:1)

比经过测试的解决方案更值得思考。

XML文件支持实体在解析过程中从其他文件内联文本。如果看到复杂的xml文件,那么这种技术已用于模块化文件。

Properties现在支持两种文件格式,即带有键/值对的常见.properties格式和xml格式。 Properties可以加载和存储到xml文件中。

ResourceBundle有一个直接子类:PropertyResourceBundle。看起来这个类实际上仅限于较旧的键/值对格式,但它可以用于实现另一个类,如XMLPropertyResourceBundle,它能够从entity技巧的xml文件中读取属性可以帮助模块化这些文件。

如果这样做 - 将现有属性文件转换为xml属性文件应该很简单,只需使用Properties类,从标准格式读取并存储到XML。