我怎样才能找到ResourceBundle的来源?

时间:2009-09-30 13:31:39

标签: java resources properties

给定一个ResourceBundle对象,有没有办法获取一个URL或其他指示器来查找它在查找时的位置?

正在创建ResourceBundle:

ResourceBundle rb = ResourceBundle.getBundle("filename");

在大多数情况下,它是从文件subdir / filename.properties加载的。我希望能够以编程方式引用此位置,而不是硬编码。

3 个答案:

答案 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));