Quiero leer un archivo XML que se encuentra dentro de uno de los jar
incluidos en mi ruta de clase. ¿Cómo puedo leer cualquier archivo que esté incluido en el jar
?¿Cómo leer un archivo del jar en Java?
Respuesta
Si desea leer ese archivo desde el interior de su uso de la aplicación:
InputStream input = getClass().getResourceAsStream("/classpath/to/my/file");
La ruta comienza con "/", pero eso no es el camino en su sistema de archivos, pero en la ruta de clases. Por lo tanto, si su archivo está en classpath "org.xml" y se llama myxml.xml, su ruta de acceso se verá como "/org/xml/myxml.xml".
El InputStream lee el contenido de su archivo. Puede envolverlo en un lector, si lo desea.
Espero que ayude.
+1 para explicar por qué es necesario el "/" inicial. –
Ah, este es uno de mis temas favoritos. Fundamentalmente, hay dos maneras en que puede cargar un recurso a través de la ruta de clases:
Class.getResourceAsStream(resource)
y
ClassLoader.getResourceAsStream(resource)
(hay otras formas que implican obtener una URL para el recurso de una manera similar, a continuación, abrir una conexión, pero estas son las dos formas directas).
El primer método realmente delega en el segundo, después de modificar el nombre del recurso. En esencia, hay dos tipos de nombres de recursos: absoluto (por ejemplo, "/ ruta/a/recurso/recurso") y relativo (por ejemplo, "recurso"). Los caminos absolutos comienzan con "/".
Aquí hay un ejemplo que debería ilustrar. Considere una clase com.example.A. Considere dos recursos, uno ubicado en/com/example/anidado, el otro en/top, en el classpath. El programa siguiente muestra nueve posibles maneras de acceder a los dos recursos:
package com.example; public class A { public static void main(String args[]) { // Class.getResourceAsStream Object resource = A.class.getResourceAsStream("nested"); System.out.println("1: A.class nested=" + resource); resource = A.class.getResourceAsStream("/com/example/nested"); System.out.println("2: A.class /com/example/nested=" + resource); resource = A.class.getResourceAsStream("top"); System.out.println("3: A.class top=" + resource); resource = A.class.getResourceAsStream("/top"); System.out.println("4: A.class /top=" + resource); // ClassLoader.getResourceAsStream ClassLoader cl = A.class.getClassLoader(); resource = cl.getResourceAsStream("nested"); System.out.println("5: cl nested=" + resource); resource = cl.getResourceAsStream("/com/example/nested"); System.out.println("6: cl /com/example/nested=" + resource); resource = cl.getResourceAsStream("com/example/nested"); System.out.println("7: cl com/example/nested=" + resource); resource = cl.getResourceAsStream("top"); System.out.println("8: cl top=" + resource); resource = cl.getResourceAsStream("/top"); System.out.println("9: cl /top=" + resource); } }
La salida del programa es:
1: A.class [email protected] 2: A.class /com/example/[email protected] 3: A.class top=null 4: A.class /[email protected] 5: cl nested=null 6: cl /com/example/nested=null 7: cl com/example/[email protected] 8: cl [email protected] 9: cl /top=null
Parcialmente cosas hacen lo que cabría esperar. El Caso-3 falla porque la resolución relativa de la clase es con respecto a la Clase, por lo que "arriba" significa "/ com/example/top", pero "/ top" significa lo que dice.
Case-5 falla porque la resolución relativa del cargador de clases está con respecto al cargador de clases. Pero, inesperadamente, Case-6 también falla: uno podría esperar que "/ com/example/anidado" se resolviera correctamente. Para acceder a un recurso anidado a través del cargador de clases, necesita utilizar Case-7, es decir, la ruta anidada es relativa a la raíz del cargador de clases. Del mismo modo, Case-9 falla, pero Case-8 pasa.
Recuerde: para java.lang.Class, getResourceAsStream() no delegar en el cargador de clases:
public InputStream getResourceAsStream(String name) { name = resolveName(name); ClassLoader cl = getClassLoader0(); if (cl==null) { // A system class. return ClassLoader.getSystemResourceAsStream(name); } return cl.getResourceAsStream(name); }
por lo que es el comportamiento de ResolveName() que es importante.
Finalmente, dado que es el comportamiento del cargador de clases que cargó la clase que esencialmente controla getResourceAsStream(), y el cargador de clases suele ser un cargador personalizado, las reglas de carga de recursos pueden ser aún más complejas. p.ej.para aplicaciones web, cargue desde WEB-INF/classes o WEB-INF/lib en el contexto de la aplicación web, pero no desde otras aplicaciones web que estén aisladas. Además, los cargadores de clases de buen comportamiento delegan a los padres, por lo que los recursos duplicados en el classpath pueden no ser accesibles usando este mecanismo.
Esta es esencialmente la misma respuesta que di, pero explicada en gran parte más detalles. +1 – Mnementh
Aquí está el método resolveName que se mencionó: https://gist.github.com/briangordon/5374626 –
Un JAR es básicamente un archivo ZIP, así que trátelo como tal. A continuación, se incluye un ejemplo sobre cómo extraer un archivo de un archivo WAR (también trátelo como un archivo ZIP) y muestra el contenido de la cadena. Para el binario necesitarás modificar el proceso de extracción, pero hay muchos ejemplos para eso.
public static void main(String args[]) {
String relativeFilePath = "style/someCSSFile.css";
String zipFilePath = "/someDirectory/someWarFile.war";
String contents = readZipFile(zipFilePath,relativeFilePath);
System.out.println(contents);
}
public static String readZipFile(String zipFilePath, String relativeFilePath) {
try {
ZipFile zipFile = new ZipFile(zipFilePath);
Enumeration<? extends ZipEntry> e = zipFile.entries();
while (e.hasMoreElements()) {
ZipEntry entry = (ZipEntry) e.nextElement();
// if the entry is not directory and matches relative file then extract it
if (!entry.isDirectory() && entry.getName().equals(relativeFilePath)) {
BufferedInputStream bis = new BufferedInputStream(
zipFile.getInputStream(entry));
// Read the file
// With Apache Commons I/O
String fileContentsStr = IOUtils.toString(bis, "UTF-8");
// With Guava
//String fileContentsStr = new String(ByteStreams.toByteArray(bis),Charsets.UTF_8);
// close the input stream.
bis.close();
return fileContentsStr;
} else {
continue;
}
}
} catch (IOException e) {
logger.error("IOError :" + e);
e.printStackTrace();
}
return null;
}
En este ejemplo estoy usando Apache Commons E/S y si está utilizando Maven aquí es la dependencia:
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
Comprobar primero el cargador de clases.
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
if (classLoader == null) {
classLoader = Class.class.getClassLoader();
}
classLoader.getResourceAsStream("xmlFileNameInJarFile.xml");
// xml file location at xxx.jar
// + folder
// + folder
// xmlFileNameInJarFile.xml
simplemente para la corrección, se ha producido recientemente un question en la lista de correo Jython, donde una de las respuestas se hace referencia a este hilo.
La pregunta era cómo llamar a un script en Python que está contenida en un archivo .jar desde dentro Jython, la respuesta sugerida es la siguiente (con "InputStream" como se explica en una de las respuestas anteriores:
PythonInterpreter.execfile(InputStream)
- 1. Cómo leer un archivo dentro de un Jar con JRuby
- 2. ¿Cómo leer un archivo de un archivo jar?
- 3. Leer archivo de propiedades fuera del archivo JAR
- 4. Cómo leer el archivo MANIFEST.MF del JAR usando Bash
- 5. leyendo el archivo MANIFEST.MF del archivo jar usando JAVA
- 6. Java: leer un archivo en una matriz
- 7. Ejecutar archivo .jar desde un programa Java
- 8. ¿Cómo leer un archivo XML con Java?
- 9. Cómo ejecutar un archivo JAR
- 10. Leer archivos de una carpeta dentro de un archivo jar
- 11. código Java para crear un archivo JAR
- 12. Cómo un archivo jar puede leer un archivo de propiedades externo
- 13. ¿Cómo puedo convertir un archivo JAR en un archivo EXE?
- 14. ¿Cómo puedo ejecutar un archivo .jar en java
- 15. Cómo ejecutar un archivo jar en Eclipse
- 16. ¿Cómo leo un archivo de recursos de un archivo jar de Java?
- 17. Cómo crear un archivo Jar en Netbeans
- 18. Java: Exponer solo un paquete en un archivo jar
- 19. ¿Cómo leer un archivo en una cadena en java?
- 20. Cargando un archivo .GIF animado del archivo JAR en ImageIcon
- 21. Archivo ejecutable Java de JAR
- 22. JAVA: leer y escribir un archivo juntos
- 23. Applet de Java en archivo JAR
- 24. Java Command Line Jar Archivo
- 25. Listar los archivos en un directorio del archivo JAR actual
- 26. Leer del archivo en Eclipse
- 27. Cómo abrir un archivo txt y leer números en Java
- 28. ¿Cómo compilo un archivo java que tiene dependencias jar?
- 29. Cómo crear un archivo .jar o export jar en IntelliJ (como eclipse java archive export)
- 30. ¿Cómo leer el contenido del archivo desde un archivo?
ver http://stackoverflow.com/questions/16842306 – yegor256
Si desea leer archivos de un directorio en jar con cualquier número de archivos, consulte [Stackoverflow-Link] (https://stackoverflow.com/questions/26185137/ spring-boot-resource-not-found-when-using-executable-jar/39818817 # 39818817) –