Solución:
En lugar de tratar de abordar el recurso como un archivo, simplemente solicite al ClassLoader que devuelva un InputStream para el recurso a través de getResourceAsStream:
InputStream in = getClass().getResourceAsStream("/file.txt");
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
Siempre y cuando el file.txt
recurso está disponible en el classpath, entonces este enfoque funcionará de la misma manera independientemente de si el file.txt
recurso está en un classes/
directorio o dentro de un jar
.
los URI is not hierarchical
ocurre porque el URI de un recurso dentro de un archivo jar se verá así: file:/example.jar!/file.txt
. No puede leer las entradas dentro de un jar
(a zip
file) como si fuera un simple archivo antiguo.
Esto se explica bien por las respuestas a:
- ¿Cómo leo un archivo de recursos de un archivo jar de Java?
- Archivo Jar de Java: errores de uso de recursos: el URI no es jerárquico
Para acceder a un archivo en un frasco, 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, debería estar en la raíz), luego acceda a él usando
Thread.currentThread().getContextClassLoader().getResourceAsStream("file.txt")
Es posible que la primera opción no funcione cuando se utiliza jar como complemento.
Tuve este problema antes e hice un método alternativo para cargar. Básicamente, la primera forma funciona dentro del archivo .jar y la segunda forma funciona dentro de eclipse u otro IDE.
public class MyClass {
public static InputStream accessFile() {
String resource = "my-file-located-in-resources.txt";
// this is the path within the jar file
InputStream input = MyClass.class.getResourceAsStream("/resources/" + resource);
if (input == null) {
// this is how we load file within editor (eg eclipse)
input = MyClass.class.getClassLoader().getResourceAsStream(resource);
}
return input;
}
}