[英]How to load a resource bundle from a file resource in Java?
我在c:/temp
中有一個名為mybundle.txt
的文件 -
c:/temp/mybundle.txt
如何將此文件加載到java.util.ResourceBundle
? 該文件是一個有效的資源包。
這似乎不起作用:
java.net.URL resourceURL = null;
String path = "c:/temp/mybundle.txt";
java.io.File fl = new java.io.File(path);
try {
resourceURL = fl.toURI().toURL();
} catch (MalformedURLException e) {
}
URLClassLoader urlLoader = new URLClassLoader(new java.net.URL[]{resourceURL});
java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle( path ,
java.util.Locale.getDefault(), urlLoader );
只要您正確命名您的資源包文件(使用 .properties 擴展名),那么它就可以工作:
File file = new File("C:\\temp");
URL[] urls = {file.toURI().toURL()};
ClassLoader loader = new URLClassLoader(urls);
ResourceBundle rb = ResourceBundle.getBundle("myResource", Locale.getDefault(), loader);
其中“c:\temp”是保存屬性文件的外部文件夾(不在類路徑中),“myResource”與 myResource.properties、myResource_fr_FR.properties 等相關。
感謝http://www.coderanch.com/t/432762/java/java/absolute-path-bundle-file
當你說它是“一個有效的資源包”時——它是一個屬性資源包嗎? 如果是這樣,加載它的最簡單方法可能是:
try (FileInputStream fis = new FileInputStream("c:/temp/mybundle.txt")) {
return new PropertyResourceBundle(fis);
}
1) 更改屬性的擴展名(例如 mybundle.properties。)
2) 將文件放入 jar 並將其添加到類路徑中。
3) 使用此代碼訪問屬性:
ResourceBundle rb = ResourceBundle.getBundle("mybundle");
String propertyValue = rb.getString("key");
來自ResourceBundle.getBundle(String baseName)
的 JavaDocs:
baseName
- 資源包的基本名稱,一個完全限定的類名
用簡單的英語來說,這意味着資源包必須在類路徑中,而baseName
應該是包含包的包加上包名稱,在您的例子中是mybundle
。
省略擴展名和構成包名稱一部分的任何區域設置,JVM 將根據默認區域設置為您排序 - 有關更多信息,請參閱java.util.ResourceBundle上的文檔。
對於 JSF 應用程序
從給定文件路徑獲取資源包 prop 文件以在 JSF 應用程序中使用它們。
loadBundle
標簽的basename
屬性中指定類。 <f:loadBundle basename="Message" var="msg" />
有關擴展 RB 的基本實現,請參閱示例自定義資源包中的示例
/* Create this class to make it base class for Loading Bundle for JSF apps */
public class Message extends ResourceBundle {
public Messages (){
File file = new File("D:\\properties\\i18n");
ClassLoader loader=null;
try {
URL[] urls = {file.toURI().toURL()};
loader = new URLClassLoader(urls);
ResourceBundle bundle = getBundle("message", FacesContext.getCurrentInstance().getViewRoot().getLocale(), loader);
setParent(bundle);
} catch (MalformedURLException ex) { }
}
.
.
.
}
否則,從 getBundle 方法獲取包,但從Locale.getDefault()
等其他來源獲取區域設置,在這種情況下可能不需要新的 (RB) 類。
如果像我一樣,你真的想從你的文件系統而不是類路徑加載 properties 文件,但除此之外保留所有與查找相關的智能,然后執行以下操作:
java.util.ResourceBundle.Control
的子類newBundle()
方法在這個愚蠢的例子中,我假設你在C:\temp
有一個文件夾,其中包含一個簡單的“.properties”文件列表:
public class MyControl extends Control {
@Override
public ResourceBundle newBundle(String baseName, Locale locale, String format, ClassLoader loader, boolean reload)
throws IllegalAccessException, InstantiationException, IOException {
if (!format.equals("java.properties")) {
return null;
}
String bundleName = toBundleName(baseName, locale);
ResourceBundle bundle = null;
// A simple loading approach which ditches the package
// NOTE! This will require all your resource bundles to be uniquely named!
int lastPeriod = bundleName.lastIndexOf('.');
if (lastPeriod != -1) {
bundleName = bundleName.substring(lastPeriod + 1);
}
InputStreamReader reader = null;
FileInputStream fis = null;
try {
File file = new File("C:\\temp\\mybundles", bundleName);
if (file.isFile()) { // Also checks for existance
fis = new FileInputStream(file);
reader = new InputStreamReader(fis, Charset.forName("UTF-8"));
bundle = new PropertyResourceBundle(reader);
}
} finally {
IOUtils.closeQuietly(reader);
IOUtils.closeQuietly(fis);
}
return bundle;
}
}
另請注意,這支持 UTF-8,我認為默認情況下不支持它。
這對我很有用。 而且它不會每次都重新加載包。 我試圖獲取一些統計信息來從外部文件位置加載和重新加載包。
File file = new File("C:\\temp");
URL[] urls = {file.toURI().toURL()};
ClassLoader loader = new URLClassLoader(urls);
ResourceBundle rb = ResourceBundle.getBundle("myResource", Locale.getDefault(), loader);
其中“c:\temp”是保存屬性文件的外部文件夾(不在類路徑中),“myResource”與 myResource.properties、myResource_fr_FR.properties 等相關。
注意:如果您的類路徑中有相同的包名稱,那么默認情況下將使用 URLClassLoader 的這個構造函數來獲取它。
感謝http://www.coderanch.com/t/432762/java/java/absolute-path-bundle-file
在下面找到一些統計數據,所有時間都以毫秒為單位。 我不擔心初始加載時間,因為這可能與我的工作區或我試圖弄清楚的代碼有關,但我想展示的是重新加載的方式較少,告訴我它來自內存。
這里有一些統計數據:
我更願意使用 resourceboundle 類來加載屬性 - 只是通過流、Properties 類和 load() 在一行而不是 5 行代碼中完成它。
供參考....
public void init(ServletConfig servletConfig) throws ServletException {
super.init(servletConfig);
try {
/*** Type1 */
Properties props = new Properties();
String fileName = getServletContext().getRealPath("WEB-INF/classes/com/test/my.properties");
// stream = Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName);
// stream = ClassLoader.getSystemResourceAsStream("WEB-INF/class/com/test/my.properties");
InputStream stream = getServletContext().getResourceAsStream("/WEB-INF/classes/com/test/my.properties");
// props.load(new FileInputStream(fileName));
props.load(stream);
stream.close();
Iterator keyIterator = props.keySet().iterator();
while(keyIterator.hasNext()) {
String key = (String) keyIterator.next();
String value = (String) props.getProperty(key);
System.out.println("key:" + key + " value: " + value);
}
/*** Type2: */
// Just get it done in one line by rb instead of 5 lines to load the properties
// WEB-INF/classes/com/test/my.properties file
// ResourceBundle rb = ResourceBundle.getBundle("com.test.my", Locale.ENGLISH, getClass().getClassLoader());
ResourceBundle rb = ResourceBundle.getBundle("com.ibm.multitool.customerlogs.ui.nl.redirect");
Enumeration<String> keys = rb.getKeys();
while(keys.hasMoreElements()) {
String key = keys.nextElement();
System.out.println(key + " - " + rb.getObject(key));
}
} catch (IOException e) {
e.printStackTrace();
throw new ServletException("Error loading config.", e);
} catch (Exception e) {
e.printStackTrace();
throw new ServletException("Error loading config.", e);
}
}
我認為您希望文件的父級位於類路徑中,而不是實際文件本身。
試試這個(可能需要一些調整):
String path = "c:/temp/mybundle.txt";
java.io.File fl = new java.io.File(path);
try {
resourceURL = fl.getParentFile().toURL();
} catch (MalformedURLException e) {
e.printStackTrace();
}
URLClassLoader urlLoader = new URLClassLoader(new java.net.URL[]{resourceURL});
java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("mybundle.txt",
java.util.Locale.getDefault(), urlLoader );
如果您想加載不同語言的消息文件,只需使用 shared.loader= 的 catalina.properties ......有關更多信息,請訪問http://theswarmintelligence.blogspot.com/2012/08/use-resource-bundle-消息文件out.html
這對我有用:
File f = new File("some.properties");
Properties props = new Properties();
FileInputStream fis = null;
try {
fis = new FileInputStream(f);
props.load(fis);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fis != null) {
try {
fis.close();
fis = null;
} catch (IOException e2) {
e2.printStackTrace();
}
}
}
public class One {
private static One one = null;
Map<String, String> configParameter = Collections.synchronizedMap(new HashMap<String, String>());
private One() {
ResourceBundle rb = ResourceBundle.getBundle("System", Locale.getDefault());
Enumeration en = rb.getKeys();
while (en.hasMoreElements()) {
String key = (String) en.nextElement();
String value = rb.getString(key);
configParameter.put(key, value);
}
}
public static One getInstance() {
if (one == null) {
one= new One();
}
return one;
}
public Map<String, String> getParameter() {
return configParameter;
}
public static void main(String[] args) {
String string = One.getInstance().getParameter().get("subin");
System.out.println(string);
}
}
ResourceBundle rb = ResourceBundle.getBundle("service"); //service.properties
System.out.println(rb.getString("server.dns")); //server.dns=http://....
文件名應具有 .properties 擴展名,基本目錄應位於類路徑中。 否則它也可以在類路徑中的 jar 中相對於類路徑中的目錄,資源包可以用 / 或指定。 分隔器。 “。” 是首選。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.