disponibilidad comandos clusvcadm cluster alta java jar path directory filesystems

java - comandos - clusvcadm



Leer desde el sistema de archivos a través del objeto FileSystem (1)

Para listar el contenido de los archivos de un directorio específico en classpath, estoy usando las nuevas características FileSystem y Path de Java 7. En una implementación, el directorio se almacena directamente en el sistema de archivos. En otra implementación, se almacena en un archivo JAR.

Mi enfoque funciona bien con los archivos JAR: creo un objeto FileSystem que hace referencia al archivo JAR y accede al contenido a través del objeto Path .

... URI dir = ... String[] array = dir.toString().split("!"); try (final FileSystem fs = FileSystems.newFileSystem(URI.create(array[0]), new HashMap<String, Object>())) { final Path directory = fs.getPath(array[1]); try (DirectoryStream<Path> directoryStream = Files.newDirectoryStream(directory)) { ...

Debido a que el objeto dir tiene el siguiente valor, funciona:

jar:file:/C:/Users/pax/.../Detector-1.0.jar!/org/.../destinationdir

Pero en el otro entorno, el directorio de destino se almacena en el sistema de archivos, directamente. El objeto dir contiene el valor:

file:/C:/Users/pax/.../destinationdir

FileSystems.newFileSystem(...) siempre arroja la siguiente excepción para / y file:/C:/Users/pax/.../destinationdir como URI:

java.lang.IllegalArgumentException: Path component should be ''/'' at sun.nio.fs.WindowsFileSystemProvider.checkUri(WindowsFileSystemProvider.java:68)

¿Cómo se usa FileSystem.newFileSystem para los destinos en el sistema de archivos?

¿Hay un mejor enfoque para listar el contenido de los directorios independientemente de su tipo específico de almacenamiento (sistema de archivos o archivo JAR)?


La siguiente resolución de la pregunta aborda el problema ("destino en el sistema de archivos" versus "destino en el archivo JAR") mediante el enfoque try-catch: NIO2: ¿cómo mapear genéricamente un URI a un Path?

Este método de utilidad intenta obtener una instancia de Path correcta. Pero puede ocurrir un problema adicional: si este recurso de destino está contenido en un archivo JAR (en lugar de un sistema de archivos), entonces solo puede acceder al recurso a través de su instancia asociada de FileSystem que no debe cerrarse. Por lo tanto, su método de ayuda debe devolver el objeto Path así como la instancia de FileSystem (solo se requiere si no está en el sistema de archivos directamente). El invocador tiene que cerrar el objeto FileSystem , manualmente:

public static PathReference getPath(final URI resPath) throws IOException { try { // first try getting a path via existing file systems return new PathReference(Paths.get(resPath), null); } catch (final FileSystemNotFoundException e) { /* * not directly on file system, so then it''s somewhere else (e.g.: * JAR) */ final Map<String, ?> env = Collections.emptyMap(); final FileSystem fs = FileSystems.newFileSystem(resPath, env); return new PathReference(fs.provider().getPath(resPath), fs); } }

La clase de envoltura PathReference debe implementar AutoClosable para que se pueda usar en try block:

public class PathReference implements AutoCloseable { ... @Override public void close() throws Exception { if (this.fileSystem != null) this.fileSystem.close(); } public Path getPath() { return this.path; } public FileSystem getFileSystem() { return this.fileSystem; } }

Esto hace que el lanzamiento de la instancia de FileSystem un poco más transparente:

... try (final PathReference fileObj = SignatureUtils.getPath(file)) { ... try (InputStream fileStream = Files.newInputStream(fileObj.getPath())) { ...