如何从Java中的文件资源加载资源包?

时间:2009-07-23 15:07:20

标签: java resourcebundle

我在mybundle.txt -

中有一个名为c:/temp的文件

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

15 个答案:

答案 0 :(得分:57)

只要您正确命名资源包文件(扩展名为.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

答案 1 :(得分:41)

当你说它是“有效的资源包”时 - 它是属性资源包吗?如果是这样,最简单的加载方式可能是:

try (FileInputStream fis = new FileInputStream("c:/temp/mybundle.txt")) {
  return new PropertyResourceBundle(fis);
}

答案 2 :(得分:21)

1)将扩展名更改为属性(例如mybundle.properties。) 2)将文件放入jar中并将其添加到类路径中 3)使用以下代码访问属性:

ResourceBundle rb = ResourceBundle.getBundle("mybundle");
String propertyValue = rb.getString("key");

答案 3 :(得分:11)

来自ResourceBundle.getBundle(String baseName)的JavaDocs:

  

baseName - 的基本名称   资源包,一个完全合格的   班级名称

这意味着简单的英语是资源包必须在类路径上,并且baseName应该是包含包的包以及包的名称mybundle

取消扩展名和构成捆绑名称一部分的任何语言环境,JVM将根据默认语言环境为您排序 - 有关详细信息,请参阅java.util.ResourceBundle上的文档。

答案 4 :(得分:6)

对于JSF应用程序

从给定文件路径获取资源包prop文件以在JSF应用程序中使用它们。

  • 使用URLClassLoader为扩展的类设置包 ResourceBundle从文件路径加载bundle。
  • 指定basename标记的loadBundle属性的类。 <f:loadBundle basename="Message" var="msg" />

有关扩展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) { }
       }
      .
      .
      .
    }

否则,从getBundle方法获取bundle,但是从Locale.getDefault()等其他源获取locale,在这种情况下可能不需要new(RB)类。

答案 5 :(得分:2)

如果像我一样,您实际上想要从文件系统而不是类路径加载.properties文件,但是保留所有与查找相关的智能,请执行以下操作:

  1. 创建java.util.ResourceBundle.Control
  2. 的子类
  3. 覆盖newBundle()方法
  4. 在这个愚蠢的例子中,我假设你在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,我认为默认情况下不支持。

答案 6 :(得分:2)

我更喜欢使用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);
    }       

}

答案 7 :(得分:1)

我刚刚发布了一个名为Rincl的库,它可以从资源文件加载中获取所有苦差事。将自动找到以类命名的资源文件(使用常规本地分辨率)。更好的是,自动找到父类和接口的资源。此外,它还具有各种优势,例如透明地处理UTF-8属性文件和XML属性文件。

您还可以使用Rincl阅读intro或完整lesson to internationalization

答案 8 :(得分:1)

这对我很好。而且它不会每次都重新加载捆绑软件。我试图获取一些统计信息以从外部文件位置加载和重新加载捆绑软件。

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

始终以毫秒为单位查找以下一些统计信息。 我并不担心初始加载时间,因为这可能与我试图找出的工作空间或代码有关,但我试图展示的是重新加载的方式要少得多,告诉我它来自内存。

以下是一些统计信息:

  • 初始Locale_1加载了3486
  • 重新加载语言环境_1花费了24
  • 重新加载语言环境_1花费了23
  • 重新加载语言环境_1花费了22
  • 重新加载Locale_1花费了15
  • 初始语言环境_2加载了870
  • 重新加载语言环境_2花费了22
  • 重新加载语言环境_2花费了18
  • 初始Locale_3加载花费2298
  • 重新加载Locale_3花费了8
  • 重新加载Locale_3花费了4

答案 9 :(得分:0)

我认为您希望文件的位于类路径上,而不是实际文件本身。

试试这个(可能需要一些调整):

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

答案 10 :(得分:0)

文件名应该有.properties扩展名,基目录应该在classpath中。否则它也可以在类路径中的jar中 相对于类路径中的目录,可以使用/或指定资源包。分隔器。 “”是首选。

答案 11 :(得分:0)

如果您想加载不同语言的消息文件,只需使用 shared.loader = catalina.properties ... 有关详细信息,请访问http://theswarmintelligence.blogspot.com/2012/08/use-resource-bundle-messages-files-out.html

答案 12 :(得分:0)

这对我有用:

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();
        }
    }
}           

答案 13 :(得分:0)

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

    }
}

答案 14 :(得分:0)

ResourceBundle rb = ResourceBundle.getBundle("service"); //service.properties
System.out.println(rb.getString("server.dns")); //server.dns=http://....