java nio

Evite la causa de terminación de Java 8 Files.walk(..) de(java.nio.file.AccessDeniedException)



(1)

Esta pregunta ya tiene una respuesta aquí:

Descripción

Estoy usando Java 8 Files.walk(..) para contar archivos .mp3 contenidos dentro de una carpeta y todas las carpetas dentro de ella. En otras palabras, estoy visitando todos los niveles del árbol de archivos.

Cuando obtengo java.nio.file.AccessDeniedException cierra la java.nio.file.AccessDeniedException , no quiero este comportamiento. Lo necesito para ignorar o imprimir la excepción y continuar contando archivos. A continuación se muestra el código que uso :):

/** * Count files in a directory (including files in all sub * directories) * * @param directory * the directory to start in * @return the total number of files */ public int countFiles(File dir) { if (dir.exists()) try (Stream<Path> paths = Files.walk(Paths.get(dir.getPath()), FileVisitOption.FOLLOW_LINKS)) { return (int) paths.filter(path -> { // i am using something different here but i changed // it just for the purpose of StackOverFlow question return path.toString().contains(".mp3"); }).count(); } catch (IOException ex) { //Main.logger.log(Level.WARNING, "", ex); ex.printStackTrace(); } return 0; }

StackTrace of error:

java.io.UncheckedIOException: java.nio.file.AccessDeniedException: C:/$Recycle.B in/S-1-5-18 at java.nio.file.FileTreeIterator.fetchNextIfNeeded(FileTreeIterator.java:88) at java.nio.file.FileTreeIterator.hasNext(FileTreeIterator.java:104) at java.util.Iterator.forEachRemaining(Iterator.java:115) at java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.jav a:1801) at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481) at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471) at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708) at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) at java.util.stream.LongPipeline.reduce(LongPipeline.java:438) at java.util.stream.LongPipeline.sum(LongPipeline.java:396) at java.util.stream.ReferencePipeline.count(ReferencePipeline.java:526) at smartcontroller.SmartController$InputService$1.countFiles(SmartController.ja va:2092) ...

Pregunta similar, aunque no es lo mismo, necesito que me devuelvan un Stream .

Evitar el acceso denegado en un árbol FileWalking en Java7 .


Responder

Aquí hay una solución temporal, que se puede mejorar para usar Java 8 Streams y Lambdas.

int[] count = {0}; try { Files.walkFileTree( Paths.get(dir.getPath()), new HashSet<FileVisitOption>(Arrays.asList(FileVisitOption.FOLLOW_LINKS)), Integer.MAX_VALUE, new SimpleFileVisitor<Path>() { @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { System.out.printf("Visiting file %s/n", file); ++count[0]; return FileVisitResult.CONTINUE; } @Override public FileVisitResult visitFileFailed(Path file, IOException e) throws IOException { System.err.printf("Visiting failed for %s/n", file); return FileVisitResult.SKIP_SUBTREE; } @Override public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { System.out.printf("About to visit directory %s/n", dir); return FileVisitResult.CONTINUE; } }); } catch (IOException e) { // handle exception }