[英]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.