Me gustaría leer un recurso desde mi jar de la siguiente manera:
File file;
file = new File(getClass().getResource("/file.txt").toURI());
BufferredReader reader = new BufferedReader(new FileReader(file));
//Read the file
y funciona bien cuando lo ejecuto en Eclipse, pero si lo exporto a un jar y lo ejecuto, hay una IllegalArgumentException:
Exception in thread "Thread-2"
java.lang.IllegalArgumentException: URI is not hierarchical
y realmente no sé por qué, pero con algunas pruebas encontré si cambio
file = new File(getClass().getResource("/file.txt").toURI());
a
file = new File(getClass().getResource("/folder/file.txt").toURI());
entonces funciona al contrario (funciona en jar pero no eclipse).
Estoy usando Eclipse y la carpeta con mi archivo está en una carpeta de clase.
getResourceAsStream
sigue siendo una solución más simple y más portátil para el problema.Respuestas:
En lugar de tratar de abordar el recurso como un archivo, simplemente solicite al ClassLoader que devuelva un InputStream para el recurso en su lugar a través de getResourceAsStream :
Mientras el
file.txt
recurso esté disponible en el classpath, este enfoque funcionará de la misma manera, independientemente de si elfile.txt
recurso está en unclasses/
directorio o dentro de ajar
.El
URI is not hierarchical
se produce porque la URI de un recurso dentro de un archivo JAR se va a ver algo como esto:file:/example.jar!/file.txt
. No puede leer las entradas dentro de unjar
(unzip
archivo) como si fuera un archivo antiguo simple .Esto se explica bien por las respuestas a:
fuente
InputStream
existe (me gustaFile.exists()
) para que mi juego pueda saber si usar el archivo predeterminado o no. Gracias.getClass().getResource("**/folder**/file.txt")
que funcionó es porque tenía esa carpeta en el mismo directorio que mi jar :).getResourceAsStream
devuelve nulo si el recurso no existe para que pueda ser su prueba de "existe".Para acceder a un archivo en un jar tiene dos opciones:
Coloque el archivo en la estructura de directorios que coincida con el nombre de su paquete (después de extraer el archivo .jar, debe estar en el mismo directorio que el archivo .class), luego acceda a él usando
getClass().getResourceAsStream("file.txt")
Coloque el archivo en la raíz (después de extraer el archivo .jar, debe estar en la raíz), luego acceda usando
Thread.currentThread().getContextClassLoader().getResourceAsStream("file.txt")
Es posible que la primera opción no funcione cuando jar se usa como complemento.
fuente
Tuve este problema antes e hice una forma alternativa de cargar. Básicamente, la primera forma de trabajar dentro del archivo .jar y la segunda forma de trabajo dentro del eclipse u otro IDE.
fuente
Hasta ahora (diciembre de 2017), esta es la única solución que encontré que funciona tanto dentro como fuera del IDE.
Utilice PathMatchingResourcePatternResolver
Nota: funciona también en spring-boot
En este ejemplo, estoy leyendo algunos archivos ubicados en src / main / resources / my_folder :
fuente
El problema es que ciertas bibliotecas de terceros requieren nombres de ruta de archivo en lugar de secuencias de entrada. La mayoría de las respuestas no abordan este problema.
En este caso, una solución es copiar el contenido del recurso en un archivo temporal. El siguiente ejemplo usa jUnit's
TemporaryFolder
.fuente
Si quieres leer como un archivo, creo que todavía hay una solución similar:
fuente
file:
URL.Asegúrese de trabajar con el separador correcto. Reemplacé todo
/
en un camino relativo con aFile.separator
. Esto funcionó bien en el IDE, sin embargo, no funcionó en el JAR de compilación.fuente
Creo que esto también debería funcionar en Java. El siguiente código que uso está usando kotlin.
fuente
He encontrado una solución
Reemplace "Principal" con la clase de Java en la que lo codificó. Reemplace "ruta" con la ruta dentro del archivo jar.
por ejemplo, si coloca State1.txt en el paquete com.issac.state, escriba la ruta como "/ com / issac / state / State1" si ejecuta Linux o Mac. Si ejecuta Windows, escriba la ruta como "\ com \ issac \ state \ State1". No agregue la extensión .txt al archivo a menos que ocurra la excepción Archivo no encontrado.
fuente
Puede usar el cargador de clases que leerá desde classpath como ruta ROOT (sin "/" al principio)
fuente
Si está utilizando spring, puede usar el siguiente método para leer el archivo de src / main / resources:
fuente
Por alguna razón,
classLoader.getResource()
siempre regresó nulo cuando implementé la aplicación web en WildFly 14. obteniendo classLoadergetClass().getClassLoader()
oThread.currentThread().getContextClassLoader()
devuelve nulo.getClass().getClassLoader()
API doc dice:"Devuelve el cargador de clases para la clase. Algunas implementaciones pueden usar nulo para representar el cargador de clases bootstrap. Este método devolverá nulo en tales implementaciones si el cargador de clases bootstrap cargó esta clase".
puede ser si está utilizando WildFly y su aplicación web intente esto
request.getServletContext().getResource()
devolvió la URL del recurso. Aquí la solicitud es un objeto de ServletRequest.fuente
El siguiente código funciona con Spring boot (kotlin):
fuente