¿Cómo cargar un paquete de recursos desde un recurso de archivo en Java?

Tengo un archivo llamado mybundle.txt en c:/temp

c:/temp/mybundle.txt

¿Cómo cargo este archivo en un java.util.ResourceBundle ? El archivo es un paquete de recursos válido.

Parece que esto no funciona:

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

Siempre que nombre los archivos del paquete de recursos correctamente (con una extensión .properties), esto funciona:

 File file = new File("C:\\temp"); URL[] urls = {file.toURI().toURL()}; ClassLoader loader = new URLClassLoader(urls); ResourceBundle rb = ResourceBundle.getBundle("myResource", Locale.getDefault(), loader); 

donde “c: \ temp” es la carpeta externa (NO en el classpath) que contiene los archivos de propiedades, y “myResource” se refiere a myResource.properties, myResource_fr_FR.properties, etc.

Crédito a http://www.coderanch.com/t/432762/java/java/absolute-path-bundle-file

Cuando dice que es “un paquete de recursos válido”, ¿es un paquete de recursos de propiedad? Si es así, la forma más simple de cargarlo probablemente sea:

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

1) Cambie la extensión a las propiedades (por ejemplo, mybundle.properties).
2) Coloque su archivo en un contenedor y agréguelo a su classpath.
3) Acceda a las propiedades usando este código:

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

De los JavaDocs para ResourceBundle.getBundle(String baseName) :

baseName : el nombre base del paquete de recursos, un nombre de clase completamente calificado

Lo que esto significa en inglés simple es que el paquete de recursos debe estar en el classpath y que baseName debe ser el paquete que contiene el paquete más el nombre del paquete, mybundle en su caso.

Deje de lado la extensión y cualquier configuración regional que forme parte del nombre del paquete, la JVM lo ordenará de acuerdo con la configuración regional predeterminada; consulte los documentos en java.util.ResourceBundle para obtener más información.

Para la aplicación JSF

Para obtener archivos prop de paquete de recursos de una ruta de archivo determinada para usarlos en una aplicación JSF.

  • Establezca el paquete con URLClassLoader para una clase que amplíe ResourceBundle para cargar el paquete desde la ruta del archivo.
  • Especifique la clase en la propiedad del basename de la etiqueta loadBundle .

Para la implementación básica de RB extendido, consulte la muestra en 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) { } } . . . } 

De lo contrario, obtenga el paquete del método getBundle pero la configuración regional de otras fonts como Locale.getDefault() , la nueva clase (RB) puede no requerir en este caso.

Si, como yo, realmente desea cargar los archivos .properties de su sistema de archivos en lugar de la ruta de acceso de clase, pero mantenga todas las funciones relacionadas con la búsqueda, haga lo siguiente:

  1. Crea una subclase de java.util.ResourceBundle.Control
  2. Anular el método newBundle()

En este ejemplo tonto, supongo que tienes una carpeta en C:\temp que contiene una lista plana de archivos “.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; } 

}

Tenga en cuenta también que esto es compatible con UTF-8, que en mi opinión no es compatible por defecto de lo contrario.

Preferiría usar la clase de enlace de recursos para cargar las propiedades, solo para hacerlo en una línea en lugar de 5 líneas de código a través de la secuencia, clase de propiedades y carga ().

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

Acabo de lanzar una biblioteca llamada Rincl que quita todo el trabajo pesado de la carga de archivos de recursos. Los archivos de recursos nombrados después de las clases se encuentran automáticamente (usando la resolución local normal). Aún mejor, los recursos para las clases principales y las interfaces se encuentran automáticamente. Además, tiene todo tipo de beneficios, como el manejo de archivos de propiedades UTF-8 y archivos de propiedades XML de forma transparente.

También puede leer una introducción o una lección completa sobre internacionalización usando Rincl.

Esto funcionó muy bien para mí. Y no recarga el paquete cada vez. Traté de tomar algunas estadísticas para cargar y volver a cargar el paquete desde la ubicación del archivo externo.

 File file = new File("C:\\temp"); URL[] urls = {file.toURI().toURL()}; ClassLoader loader = new URLClassLoader(urls); ResourceBundle rb = ResourceBundle.getBundle("myResource", Locale.getDefault(), loader); 

donde “c: \ temp” es la carpeta externa (NO en el classpath) que contiene los archivos de propiedades, y “myResource” se refiere a myResource.properties, myResource_fr_FR.properties, etc.

Nota: Si tiene el mismo nombre de paquete en su classpath, se seleccionará de forma predeterminada utilizando este constructor de URLClassLoader.

Crédito a http://www.coderanch.com/t/432762/java/java/absolute-path-bundle-file

Encuentra algunas de las estadísticas a continuación, todo el tiempo en ms. No estoy preocupado por el tiempo de carga inicial, ya que podría tratarse de algo con mi área de trabajo o código, pero lo que estoy tratando de mostrar es que la recarga tomó menos tiempo y me dijo que viene de la memoria.

Aquí algunas de las estadísticas:

  • La carga inicial de Locale_1 tomó 3486
  • Recargar Locale_1 tomó 24
  • Recargar Locale_1 tomó 23
  • Recargar Locale_1 tomó 22
  • Recargar Locale_1 tomó 15
  • La carga inicial de Locale_2 tomó 870
  • Recargar Locale_2 tomó 22
  • Recargar Locale_2 tomó 18
  • La carga inicial de Locale_3 tomó 2298
  • Recargar Locale_3 tomó 8
  • Recargar Locale_3 tomó 4

Creo que quieres que el padre del archivo esté en el classpath, no el archivo en sí.

Pruebe esto (puede necesitar algunos ajustes):

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

El nombre del archivo debe tener extensión .properties y el directorio base debe estar en classpath. De lo contrario, también puede estar en un jar que está en classpath. Relativo al directorio en classpath, el paquete de recursos se puede especificar con / o. separador. “.” se prefiere.

Si desea cargar archivos de mensajes para diferentes idiomas, solo use el archivo shared.loader = de catalina.properties … para obtener más información, visite http://theswarmintelligence.blogspot.com/2012/08/use-resource-bundle- messages-files-out.html

Esto funciona para mí:

 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 configParameter = Collections.synchronizedMap(new HashMap()); 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 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://....