2009-09-30 33 views
2

給定一個資源包對象,有沒有辦法讓一個URL或其他指示在何處發現,當它被擡起頭來?如何找出ResourceBundle的來源?

資源包正在與創建:

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

而且它正在從一個文件子目錄/ filename.properties加載,在大多數情況下。我希望能夠以編程方式引用此位置,而不是對其進行硬編碼。

回答

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

這就是你如何得到給定一類資源包。 OP正在詢問如何獲得給定ResourceBundle的文件/類/ URL,該ResourceBundle正在上游而不是下游。 – 2009-09-30 13:50:39

+0

謝謝!這幾乎是我所做的。然後,因爲我有我如何獲得資源包擺在首位的控制,我回去,並投它,只是加載Properties對象從URL,重用URL後,當我需要去文件,新文件( location.toURI()) – skiphoppy 2009-09-30 16:30:19

2

documentation來看,你不能,因爲它是可以以任意方式被繼承一個類(不一定與URL或類名相關),而且也沒有聯動回到創作者。

另請注意PropertyResourceBundle的構造函數:它需要一個InputStream,它可以在任何地方獲得:您可以通過繼承它的子類來提供您自己的InputStream,以提供隨意生成的任意數據。

2

如果你可以修改ResourceBundle.getResource所有invokations,你可以通過自己實現的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的每次調用。由於資源束被緩存,你不能確定每個bundle的檢索實際上會加載它,這是Control實現捕獲它的必要條件。

加載軟件包後,您可以使用靜態getSourceURL方法,發現從它被實際加載的網址:

ResourceBundle rb = ResourceBundle.getBundle(
    "props.Default", new ResourceBundleSourceControl()); 
System.out.println(
    "URL: " + ResourceBundleSourceControl.getSourceURL(rb));