una ruta proyecto obtener leer dentro carpeta archivo java nio zipfile

leer - obtener la ruta de mi proyecto en java



Obteniendo FileSystemNotFoundException de ZipFileSystemProvider al crear una ruta a un recurso (4)

Tengo un proyecto de Maven y dentro de un método quiero crear una ruta para un directorio en mi carpeta de recursos. Esto se hace así:

try { final URI uri = getClass().getResource("/my-folder").toURI(); Path myFolderPath = Paths.get(uri); } catch (final URISyntaxException e) { ... }

El URI generado se ve como jar:file:/C:/path/to/my/project.jar!/my-folder .

El stacktrace es el siguiente:

Exception in thread "pool-4-thread-1" java.nio.file.FileSystemNotFoundException at com.sun.nio.zipfs.ZipFileSystemProvider.getFileSystem(ZipFileSystemProvider.java:171) at com.sun.nio.zipfs.ZipFileSystemProvider.getPath(ZipFileSystemProvider.java:157) at java.nio.file.Paths.get(Paths.java:143)

El URI parece ser válido. La parte anterior ! apunta al archivo jar generado y la parte posterior a my-folder en la raíz del archivo. He usado estas instrucciones antes para crear rutas a mis recursos. ¿Por qué estoy recibiendo una excepción ahora?


Además de @Uwe Allner y @mvreijn:

Ten cuidado con la URI . A veces, el URI tiene un formato incorrecto (por ejemplo, "file:/path/..." y el correcto sería "file:///path/..." ) y no puede obtener un sistema de "file:///path/..." adecuado.
En este caso, es toUri() que el URI se cree a partir del método toUri() de la Path .

En mi caso, modifiqué un poco el método initFileSystem y utilicé en casos no excepcionales FileSystems.newFileSystem(uri, Collections.emptyMap()) . En casos excepcionales, se usa FileSystems.getDefault() .

En mi caso, también fue necesario capturar la IllegalArgumentException para manejar el caso con el Path component should be ''/'' . En Windows y Linux, la excepción se captura, pero FileSystems.getDefault() funciona. En osx no ocurre ninguna excepción y se crea el newFileSystem :

private FileSystem initFileSystem(URI uri) throws IOException { try { return FileSystems.newFileSystem(uri, Collections.emptyMap()); }catch(IllegalArgumentException e) { return FileSystems.getDefault(); } }


Ampliando la excelente respuesta de @Uwe Allner, un método a prueba de fallos para usar es

private FileSystem initFileSystem(URI uri) throws IOException { try { return FileSystems.getFileSystem(uri); } catch( FileSystemNotFoundException e ) { Map<String, String> env = new HashMap<>(); env.put("create", "true"); return FileSystems.newFileSystem(uri, env); } }

Si lo llama con el URI que está a punto de cargar, se asegurará de que el sistema de archivos esté funcionando correctamente. Siempre llamo a FileSystem.close() después de usarlo:

FileSystem zipfs = initFileSystem(fileURI); filePath = Paths.get(fileURI); // Do whatever you need and then close the filesystem zipfs.close();


Debe crear el sistema de archivos antes de poder acceder a la ruta dentro del zip como

final URI uri = getClass().getResource("/my-folder").toURI(); Map<String, String> env = new HashMap<>(); env.put("create", "true"); FileSystem zipfs = FileSystems.newFileSystem(uri, env); Path myFolderPath = Paths.get(uri);

Esto no se hace automáticamente.

Consulte http://docs.oracle.com/javase/7/docs/technotes/guides/io/fsp/zipfilesystemprovider.html


Si pretende leer el archivo de recursos, puede usar directamente getClass.getResourceAsStream . Esto configurará el sistema de archivos implícitamente. La función devuelve un null si no se pudo encontrar su recurso; de lo contrario, tendrá un flujo de entrada para analizar su recurso.