rendimiento productividad portuario portuaria medicion indicadores gestion contenedores java-8 java-stream

java-8 - productividad - medicion del rendimiento portuario



¿Las operaciones de la terminal cierran la corriente? (2)

dirPath contiene 200k archivos. Quiero leerlos uno por uno y procesarlos. El siguiente fragmento provoca java.nio.file.FileSystemException: dirPath/file-N Too many open files . ¿No se supone que la operación del terminal para forEach() cierra la secuencia abierta (es decir, el archivo abierto) antes de pasar al siguiente? En otras palabras, ¿tengo que agregar try-with-resources para los archivos transmitidos?

Files.list(dirPath) .forEach(filePath -> { Files.lines(filePath).forEach() { ... } });


Un anidado para forEach es la herramienta incorrecta, en la mayoría de los casos.

El código

Files.list(dirPath).forEach(filePath -> Files.lines(filePath).forEach(line -> { ... });

puede y debe ser reemplazado por

Files.list(dirPath).flatMap(filePath -> Files.lines(filePath)).forEach(line -> { ... });

o bueno, ya que no es tan fácil en este caso:

Files.list(dirPath).flatMap(filePath -> { try { return Files.lines(filePath);} catch(IOException ex) { throw new UncheckedIOException(ex); } }).forEach(line -> { });

como efecto secundario, obtienes lo siguiente gratis:

Stream.flatMap(…) :

Cada flujo mapeado se cierra después de que su contenido se haya colocado en esta secuencia.

Entonces esa es la solución preferida. O bueno, para hacerlo completamente correcto:

try(Stream<Path> dirStream = Files.list(dirPath)) { dirStream.flatMap(filePath -> { try { return Files.lines(filePath);} catch(IOException ex) { throw new UncheckedIOException(ex); } }).forEach(line -> { }); }


No forEach no cierra la secuencia (creada por Files.list o Files.lines ). Está documentado en javadoc, por ejemplo para Files.list :

La secuencia devuelta encapsula un Reader. Si se requiere la eliminación oportuna de los recursos del sistema de archivos, se debe utilizar la construcción try-with-resources para garantizar que el método de cierre de la secuencia se invoque después de que se completen las operaciones de la secuencia.