How to load a resource bundle from a file resource in Java?

Viewed 232588

I have a file called mybundle.txt in c:/temp -

c:/temp/mybundle.txt

How do I load this file into a java.util.ResourceBundle? The file is a valid resource bundle.

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

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

From the JavaDocs for ResourceBundle.getBundle(String baseName):

baseName - the base name of the resource bundle, a fully qualified class name

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.

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.ResourceBundle for more info.

This worked for me very well. And it doesn't reload the bundle everytime. I tried to take some stats to load and reload the bundle from external file location.

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.

Note: If you have the same bundle name on your classpath then it will be picked up by default using this constructor of URLClassLoader.

Credit to http://www.coderanch.com/t/432762/java/java/absolute-path-bundle-file

Find some of the stats below, all time in ms. I am not worried about the initial load time as that could be something with my workspace or code that I am trying to figure out but what I am trying to show is the reload took way lesser telling me its coming from memory.

Here some of the stats:

  • Initial Locale_1 load took 3486
  • Reload Locale_1 took 24
  • Reload Locale_1 took 23
  • Reload Locale_1 took 22
  • Reload Locale_1 took 15
  • Initial Locale_2 load took 870
  • Reload Locale_2 took 22
  • Reload Locale_2 took 18
  • Initial Locale_3 load took 2298
  • Reload Locale_3 took 8
  • Reload Locale_3 took 4

I think that you want the file's parent to 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 );
Related