Estoy cargando un archivo de texto desde un paquete en un JAR compilado de mi proyecto Java. La estructura de directorio relevante es la siguiente:
/src/initialization/Lifepaths.txt
Mi código carga un archivo llamando Class::getResourceAsStream
para devolver a InputStream
.
public class Lifepaths {
public static void execute() {
System.out.println(Lifepaths.class.getClass().
getResourceAsStream("/initialization/Lifepaths.txt"));
}
private Lifepaths() {}
//This is temporary; will eventually be called from outside
public static void main(String[] args) {execute();}
}
La impresión siempre se imprimirá null
, no importa lo que use. No estoy seguro de por qué lo anterior no funcionaría, así que también he intentado:
"/src/initialization/Lifepaths.txt"
"initialization/Lifepaths.txt"
"Lifepaths.txt"
Ninguno de estos trabajos. Hasta ahora he leído numerosas preguntas sobre el tema, pero ninguna de ellas ha sido útil, por lo general, solo dicen que cargue archivos usando la ruta raíz, lo que ya estoy haciendo. Eso, o simplemente carga el archivo desde el directorio actual (solo carga filename
), que también he intentado. El archivo se está compilando en el JAR en la ubicación apropiada con el nombre apropiado.
¿Cómo puedo solucionar esto?
Lifepaths.class
. Dicho esto, ¿por quégetClassLoader()
permite que funcione? (¡Además, siéntase libre de publicar una respuesta!)Lifepaths.getClass()
? No existe tal método estático definido en Object ...getResource(String)
. Por cierto, siempre he tenido problemas para que cualquiera de los dos trabaje en unstatic
contexto. El problema es básicamente que el cargador de clases obtenido es el destinado a las clases J2SE. Debe obtener acceso al cargador de clases de contexto destinado a la aplicación misma.Respuestas:
Lifepaths.class.getClass().getResourceAsStream(...)
carga recursos usando el cargador de clases del sistema, obviamente falla porque no ve sus JARLifepaths.class.getResourceAsStream(...)
carga recursos utilizando el mismo cargador de clases que cargó la clase Lifepaths y debería tener acceso a los recursos en sus JARfuente
/
antes de su ruta si su archivo está en un directorio diferente; por ejemploinitialization/Lifepaths.txt
. Si la ruta del archivo es la misma de su clase (pero bajo los recursos como directorio principal), puede poner el nombre del archivo sin ninguno/
. Por ejemplo, si su clase tiene la siguiente rutasrc/main/java/paths/Lifepaths.java
, su archivo debe tener esta rutasrc/main/resources/paths/Lifepaths.txt
.Las reglas son las siguientes:
Y prueba:
en vez de
(no estoy seguro si hace la diferencia, pero el primero usará el ClassLoader / JAR correcto, mientras que no estoy seguro con el último)
fuente
Por lo tanto, hay varias formas de obtener un recurso de un jar y cada una tiene una sintaxis ligeramente diferente en la que la ruta debe especificarse de manera diferente.
La mejor explicación que he visto es este artículo de JavaWorld . Resumiré aquí, pero si quieres saber más, debes consultar el artículo.
Métodos
1)
ClassLoader.getResourceAsStream()
.Formato: "/" - nombres separados; sin "/" inicial (todos los nombres son absolutos).
Ejemplo:
this.getClass().getClassLoader().getResourceAsStream("some/pkg/resource.properties");
2)
Class.getResourceAsStream()
Formato: "/" - nombres separados; los "/" iniciales indican nombres absolutos; todos los demás nombres son relativos al paquete de la clase
Ejemplo:
this.getClass().getResourceAsStream("/some/pkg/resource.properties");
fuente
No utilice rutas absolutas, haga que sean relativas al directorio de 'recursos' en su proyecto. Código rápido y sucio que muestra el contenido de MyTest.txt desde el directorio 'recursos'.
fuente
Es posible que desee probar esto para obtener la transmisión, es decir, primero obtenga la URL y luego ábrala como transmisión.
Una vez tuve una pregunta similar: la lectura del archivo txt del jar falla pero la imagen funciona
fuente
Parece que hay un problema con el ClassLoader que está utilizando. Use contextClassLoader para cargar la clase. Esto es independiente de si está en un método estático / no estático
Thread.currentThread().getContextClassLoader().getResourceAsStream
......fuente
Me encontré en un problema similar. Como estoy usando Maven, necesitaba actualizar mi pom.xml para incluir algo como esto:
Tenga en cuenta la etiqueta de recursos allí para especificar dónde está esa carpeta. Si tiene proyectos anidados (como yo), es posible que desee obtener recursos de otras áreas en lugar de solo en el módulo en el que está trabajando. Esto ayuda a reducir el mantenimiento del mismo archivo en cada repositorio si está utilizando datos de configuración similares
fuente
Lo que funcionó para mí fue agregar el archivo
My Project/Java Resources/src
y luego usarNo necesitaba agregar explícitamente este archivo a la ruta (agregarlo a
/src
eso aparentemente)fuente
No sé si es útil, pero en mi caso tenía mi recurso en la carpeta / src / y recibía este error. Luego moví la imagen a la carpeta bin y solucionó el problema.
fuente
Asegúrese de que su directorio de recursos (por ejemplo, "src") esté en su classpath (asegúrese de que sea un directorio fuente en su ruta de compilación en eclipse).
Asegúrese de que clazz se carga desde el cargador de clases principal.
Luego, para cargar src / initialization / Lifepaths.txt, use
Por qué:
clazz.getResourcesAsStream(foo)
busca foo desde el classpath de clazz , en relación con el directorio en el que vive clazz . El "/" inicial hace que se cargue desde la raíz de cualquier directorio en el classpath de clazz.A menos que esté en un contenedor de algún tipo, como Tomcat, o esté haciendo algo con ClassLoaders directamente, puede tratar su eclipse / línea de comando classpath como el único classloader classpath.
fuente
El cargador de clases JVM predeterminada utilizará padre-cargador de clases para cargar recursos en primer lugar: .
Lifepaths.class.getClass()
El cargador de clases esbootstrap classloader
, porgetResourceAsStream
lo que buscará solo $ JAVA_HOME, independientemente del usuario proporcionadoclasspath
. Obviamente, Lifepaths.txt no está allí.Lifepaths.class
El cargador de clases essystem classpath classloader
, porgetResourceAsStream
lo tanto , buscará definido por el usuarioclasspath
y Lifepaths.txt está allí.Al usar
java.lang.Class#getResourceAsStream(String name)
, el nombre que no comienza con '/' se agregarápackage name
como prefijo. Si desea evitar esto, utilicejava.lang.ClassLoader#getResourceAsStream
. Por ejemplo:fuente
Mas o menos:
getClass().getResource("/")
~ =Thread.currentThread().getContextClassLoader().getResource(".")
Suponga que la estructura de su proyecto es la siguiente:
fuente
Si está utilizando Maven, asegúrese de que su embalaje sea "frasco" y no "pom".
fuente
Lo que realmente necesita es un classPath absoluto completo para el archivo. Entonces, en lugar de adivinarlo, intente averiguar la RAÍZ y luego mueva el archivo a una mejor ubicación base una estructura de archivo <.war> ...
fuente
Lo que funcionó para mí es que coloqué el archivo debajo
y
fuente
src/main/JAVA
, obviamente, sus archivos sin código no deben ubicarse aquí.@Emracool ... Te sugiero una alternativa. Ya que parece estar intentando cargar un archivo * .txt. Mejor usar en
FileInputStream()
lugar de este molestogetClass().getClassLoader().getResourceAsStream()
ogetClass().getResourceAsStream()
. Al menos su código se ejecutará correctamente.fuente