如何从 Java 中的文件资源加载资源包?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1172424/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to load a resource bundle from a file resource in Java?
提问by
I have a file called mybundle.txt
in c:/temp
-
我有一个名为mybundle.txt
在c:/temp
-
c:/temp/mybundle.txt
c:/temp/mybundle.txt
How do I load this file into a java.util.ResourceBundle
? The file is a valid resource bundle.
如何将此文件加载到java.util.ResourceBundle
. 该文件是有效的资源包。
This does not seem to work:
这似乎不起作用:
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 );
回答by Jon Skeet
When you say it's "a valid resource bundle" - is it a property resource bundle? If so, the simplest way of loading it probably:
当你说它是“一个有效的资源包”时 - 它是一个属性资源包吗?如果是这样,加载它的最简单方法可能是:
try (FileInputStream fis = new FileInputStream("c:/temp/mybundle.txt")) {
return new PropertyResourceBundle(fis);
}
回答by Nick Holt
From the JavaDocs for ResourceBundle.getBundle(String baseName)
:
来自 JavaDocs 的ResourceBundle.getBundle(String baseName)
:
baseName
- the base name of the resource bundle, a fully qualified class name
baseName
- 资源包的基本名称,一个完全限定的类名
What this means in plain English is that the resource bundle must be on the classpath and that baseName
should be the package containing the bundle plus the bundle name, mybundle
in your case.
这用简单的英语意味着资源包必须在类路径上,并且在您的情况下baseName
应该是包含包和包名称的包mybundle
。
Leave off the extension and any locale that forms part of the bundle name, the JVM will sort that for you according to default locale - see the docs on java.util.ResourceBundlefor more info.
离开扩展名和构成包名称一部分的任何语言环境,JVM 将根据默认语言环境为您排序 -有关更多信息,请参阅java.util.ResourceBundle上的文档。
回答by Nick Holt
I think that you want the file's parentto be on the classpath, not the actual file itself.
我认为您希望文件的父级位于类路径上,而不是实际文件本身。
Try this (may need some tweaking):
试试这个(可能需要一些调整):
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 );
回答by Ludington
1) Change the extension to properties (ex. mybundle.properties.)
2) Put your file into a jar and add it to your classpath.
3) Access the properties using this code:
1) 将扩展名更改为 properties (例如 mybundle.properties。)
2) 将您的文件放入一个 jar 并将其添加到您的类路径中。
3)使用此代码访问属性:
ResourceBundle rb = ResourceBundle.getBundle("mybundle");
String propertyValue = rb.getString("key");
回答by Angsuman Chakraborty
The file name should have .properties extension and the base directory should be in classpath. Otherwise it can also be in a jar which is in classpath Relative to the directory in classpath the resource bundle can be specified with / or . separator. "." is preferred.
文件名应具有 .properties 扩展名,基本目录应在类路径中。否则,它也可以位于 classpath 中的 jar 中。相对于 classpath 中的目录,可以使用 / 或 指定资源包。分隔器。“。” 是首选。
回答by John
If, like me, you actually wanted to load .properties files from your filesystem instead of the classpath, but otherwise keep all the smarts related to lookup, then do the following:
如果像我一样,您确实想从文件系统而不是类路径加载 .properties 文件,但要保留与查找相关的所有智能,请执行以下操作:
- Create a subclass of
java.util.ResourceBundle.Control
- Override the
newBundle()
method
- 创建一个子类
java.util.ResourceBundle.Control
- 覆盖
newBundle()
方法
In this silly example, I assume you have a folder at C:\temp
which contains a flat list of ".properties" files:
在这个愚蠢的例子中,我假设你有一个文件夹,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;
}
}
}
Note also that this supports UTF-8, which I believe isn't supported by default otherwise.
另请注意,这支持 UTF-8,我认为默认情况下不支持。
回答by Subba Reddy
I would prefer to use the resourceboundle class to load the properties - just to get it done in one line instead of 5 lines code through stream, Properties class and load().
我更喜欢使用 resourceboundle 类来加载属性 - 只是为了在一行中完成它,而不是通过流、属性类和 load() 的 5 行代码。
FYI ....
供参考 ....
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);
}
}
回答by noboundaries
For JSF Application
对于 JSF 应用程序
To get resource bundle prop files from a given file path to use them in a JSF app.
从给定的文件路径获取资源包 prop 文件以在 JSF 应用程序中使用它们。
- Set the bundle with URLClassLoader for a class that extends ResourceBundle to load the bundle from the file path.
- Specify the class at
basename
property ofloadBundle
tag.<f:loadBundle basename="Message" var="msg" />
- 使用 URLClassLoader 为扩展 ResourceBundle 的类设置包以从文件路径加载包。
- 在标签的
basename
属性中指定类loadBundle
。<f:loadBundle basename="Message" var="msg" />
For basic implementation of extended RB please see the sample at Sample Customized Resource Bundle
有关扩展 RB 的基本实现,请参阅Sample Customized Resource Bundle 中的示例
/* 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) { }
}
.
.
.
}
Otherwise, get the bundle from getBundle method but locale from others source like Locale.getDefault()
, the new (RB)class may not require in this case.
否则,从 getBundle 方法获取包,但从其他来源获取区域设置,例如Locale.getDefault()
,在这种情况下可能不需要新的 (RB) 类。
回答by JanaVish
If you wanted to load message files for different languages, just use the shared.loader= of catalina.properties... for more info, visit http://theswarmintelligence.blogspot.com/2012/08/use-resource-bundle-messages-files-out.html
如果您想加载不同语言的消息文件,只需使用 catalina.properties... 的 shared.loader= 获取更多信息,请访问http://theswarmintelligence.blogspot.com/2012/08/use-resource-bundle-消息文件-out.html
回答by Forge_7
As long as you name your resource bundle files correctly (with a .properties extension), then this works:
只要您正确命名您的资源包文件(带有 .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);
where "c:\temp" is the external folder (NOT on the classpath) holding the property files, and "myResource" relates to myResource.properties, myResource_fr_FR.properties, etc.
其中“c:\temp”是保存属性文件的外部文件夹(不在类路径上),“myResource”与 myResource.properties、myResource_fr_FR.properties 等相关。
Credit to http://www.coderanch.com/t/432762/java/java/absolute-path-bundle-file
归功于http://www.coderanch.com/t/432762/java/java/absolute-path-bundle-file