是否可以在资源包中包含资源包文件
我们使用java.util.ResourceBundle
来加载属性信息。 我们的属性文件已经变得如此庞大,我们正在考虑将主属性文件分成几个子模块。 是否有可能实现这一目标?
master.properties ==> master.properties include moduleA.properties include moduleB.properties
让我知道?
首先,我想知道为什么你选择java.util.ResourceBundle
不是java.util.Properties
。 鉴于您的问题是如何制定的,您似乎并不关心本地化/国际化,也不关心包文件inheritance。
使用Properties
非常容易,因为它实现了Map
,而Map
又提供了一个putAll()
方法来合并另一个map。 开球示例:
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
其中您通过自定义Control
加载。
假设您在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 getKeys() { return properties != null ? (Enumeration ) 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; } } }
(琐碎的exception处理和本地化处理被放在一边,这取决于你)
这可以用作:
ResourceBundle bundle = new MultiResourceBundle("master");
但是,您可以以编程方式构造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 } }
比经过测试的解决方案更值得思考。
XML文件支持实体在解析期间从其他文件内联文本。 如果看到复杂的xml文件,那么这种技术已用于模块化文件。
Properties
现在支持两种文件格式,带有键/值对的常见.properties
格式和xml格式。 Properties
可以加载和存储到/从xml文件。
ResourceBundle
有一个直接子类: PropertyResourceBundle
。 看起来这个类实际上仅限于较旧的键/值对格式,但它可以用于实现另一个类,如XMLPropertyResourceBundle
,它能够从xml文件中读取属性,其中entity
技巧可以帮助模块化这些文件。
如果这样做 – 将现有属性文件转换为xml属性文件应该很简单,只需使用Properties
类,从标准格式读取并存储到XML。