softonic jdk descargar java java-7 tar nio2

java - descargar - jdk 1.7.0_80 download



¿Por qué Java 7 Files.walkFileTree lanza una excepción al encontrar un archivo tar en una unidad remota? (2)

Estoy usando Files.WalkFileTree() para navegar por la carpeta y contar los archivos de audio, pero hay un problema cuando encuentra un archivo tar, parece tratarlo como una carpeta real que esperaba que solo saltara por encima.

No veo ninguna opción que me permita controlar este comportamiento.

Código:

package com.jthink.songkong.fileloader; import com.jthink.songkong.cmdline.SongKong; import com.jthink.songkong.ui.MainWindow; import java.nio.file.*; import java.nio.file.attribute.BasicFileAttributes; import java.util.concurrent.Callable; import java.util.logging.Level; /** * Count the number of files that can be loaded, for information purposes only */ public class CountFilesinFolder implements Callable<Boolean> { public static class CountFiles extends SimpleFileVisitor<Path> { private int fileCount = 0; private final PathMatcher matcher; CountFiles(String pattern) { matcher = FileSystems.getDefault() .getPathMatcher("regex:" + pattern); } /** * Find Music file * * @param file * @param attr * @return */ @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attr) { Path name = file.getFileName(); if (name != null && matcher.matches(name)) { fileCount++; } return FileVisitResult.CONTINUE; } public int getFileCount() { return fileCount; } } private Path scanDir; public CountFilesinFolder(Path scanDir) { this.scanDir = scanDir; } public Boolean call() { CountFiles countFiles = null; try { countFiles = new CountFiles("^(?!._).*[.](?:mp3|mp4|m4p|m4b|m4a|ogg|flac|wma)$"); Files.walkFileTree(scanDir, countFiles); } catch (Exception e) { MainWindow.logger.log(Level.SEVERE, "Unable to find file for deriving base folder", e); } MainWindow.logger.severe("Music File Count:"+countFiles.getFileCount()); SongKong.setMaxProgress(countFiles.getFileCount()); return true; } }

da este stacktrace

java.nio.file.NoSuchFileException: Z:/Scratch/fred.tar at sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:79) at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:97) at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:102) at sun.nio.fs.WindowsDirectoryStream.<init>(WindowsDirectoryStream.java:86) at sun.nio.fs.WindowsFileSystemProvider.newDirectoryStream(WindowsFileSystemProvider.java:526) at java.nio.file.Files.newDirectoryStream(Files.java:411) at java.nio.file.FileTreeWalker.walk(FileTreeWalker.java:179) at java.nio.file.FileTreeWalker.walk(FileTreeWalker.java:199) at java.nio.file.FileTreeWalker.walk(FileTreeWalker.java:69) at java.nio.file.Files.walkFileTree(Files.java:2591) at java.nio.file.Files.walkFileTree(Files.java:2624) at com.jthink.songkong.fileloader.CountFilesinFolder.call(CountFilesinFolder.java:68) at com.jthink.songkong.fileloader.CountFilesinFolder.call(CountFilesinFolder.java:15) at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334) at java.util.concurrent.FutureTask.run(FutureTask.java:166) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) at java.lang.Thread.run(Thread.java:722)

pero esa es una unidad remota (unidad nas), no recibo ningún error en la unidad local

EDITAR Implementado el siguiente basado o la respuesta a continuación pensé que funcionó

@Override public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { if(dir.endsWith(".tar")) { return FileVisitResult.SKIP_SUBTREE; } return super.preVisitDirectory(dir, attrs); }

pero mi prueba estuvo mal, de hecho no funciona porque el código que falla en FileTreeWalker se llama antes del método previsit

try { DirectoryStream<Path> stream = null; FileVisitResult result; // open the directory try { stream = Files.newDirectoryStream(file); } catch (IOException x) { return visitor.visitFileFailed(file, x); } catch (SecurityException x) { // ignore, as per spec return FileVisitResult.CONTINUE; } // the exception notified to the postVisitDirectory method IOException ioe = null; // invoke preVisitDirectory and then visit each entry try { result = visitor.preVisitDirectory(file, attrs); if (result != FileVisitResult.CONTINUE) { return result; }


Solución para el problema en cuestión:

Pero implementa un visitFileFailed y deberías estar bien.

public class MyFileVisitor extends SimpleFileVisitor<Path> { @Override public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException { if (file.toString().endsWith(".tar")) { return FileVisitResult.CONTINUE; } return super.visitFileFailed(file, exc); } }

Actualización: si nos fijamos más, podemos ver que walkFileTree usa Files.readAttributes que se convierte en el proveedor actual en juego: WindowsFileSystemProvider.readAttributes para determinar si una ruta es un directorio.

Como alguien mencionado en los comentarios, tampoco creo que la falla esté en la implementación de Java, sino en la OS-native-call del OS-native-call que devuelve el atributo incorrecto

Si quisiera hacer una solución alternativa a esto, una opción sería implementar su propio sistema de archivos que envuelva la implementación de WindowsFileSystem de forma transparente, excepto que readAttributes devuelve .tar-paths como archivo en lugar de dir.


Tar-archives podría verse como directorio (paquete de archivos). Puede evitar este error implementando el método preVisitDirectory en su visitante simplemente devolviendo FileVisitResult.SKIP_SUBTREE para archivos-tar:

public static class CountFiles extends SimpleFileVisitor<Path> { ... public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { if (dir.toString().toLowerCase().endsWith(".tar")) { return SKIP_SUBTREE; } return super.preVisitDirectory(dir, attrs); } ... }