给定一个ResourceBundle对象,有没有办法获取一个URL或其他指示器来查找它在查找时的位置?
正在创建ResourceBundle:
ResourceBundle rb = ResourceBundle.getBundle("filename");
在大多数情况下,它是从文件subdir / filename.properties加载的。我希望能够以编程方式引用此位置,而不是硬编码。
答案 0 :(得分:2)
从documentation判断,你不能,因为它是一个可以以任意方式子类化的类(不一定与URL或类名相关联),并且没有链接回创建者。
还要注意PropertyResourceBundle的构造函数:它需要一个可以在任何地方获得的InputStream:你可以通过子类化来提供自己的InputStream,以提供凭空创建的任意数据。
答案 1 :(得分:2)
试试这个:
URL location = getClass().getClassLoader().getResource("filename.properties");
这是ResourceBundle
用于查找资源的机制。查看[Javadoc for ResourceBundle
] [1]以查看它如何将包名称映射到底层资源的细节。如果您涉及区域设置和事物,则可能需要更加聪明。
[1]:http://java.sun.com/javase/6/docs/api/java/util/ResourceBundle.html#getBundle(java.lang.String,java.util.Locale,java.lang.ClassLoader,java.util.ResourceBundle.Control)
答案 2 :(得分:2)
如果您能够修改ResourceBundle.getResource的所有调用,您可以传递自己的ResourceBundle.Control实现来缓存实际加载已解析包的URL
public class ResourceBundleSourceControl extends ResourceBundle.Control {
private static final Map<ResourceBundle, URL> sources =
new HashMap<ResourceBundle, URL>();
private String bundleName;
@Override
public ResourceBundle newBundle(String baseName, Locale locale, String format,
ClassLoader loader, boolean reload) throws IllegalAccessException,
InstantiationException, IOException {
ResourceBundle rb = super.newBundle(baseName, locale, format, loader, reload);
URL sourceURL = loader.getResource(toResourceName(bundleName, "properties"));
if(rb != null && sourceURL != null) {
synchronized(sources) {
sources.put(rb, sourceURL);
}
}
return rb;
}
@Override
public String toBundleName(String arg0, Locale arg1) {
bundleName = super.toBundleName(arg0, arg1);
return bundleName;
}
public static URL getSourceURL(ResourceBundle b) {
synchronized (sources) {
return sources.get(b);
}
}
缺点是,您必须将此类的实例传递给ResourceBundle.getBundle的每次调用。由于资源包是懒惰缓存的,因此您无法确定每个包的检索是否会实际加载它,这对于Control实现来捕获它是必要的。
加载bundle之后,你可以使用静态getSourceURL方法来查找实际加载它的URL:
ResourceBundle rb = ResourceBundle.getBundle(
"props.Default", new ResourceBundleSourceControl());
System.out.println(
"URL: " + ResourceBundleSourceControl.getSourceURL(rb));