Pregunta

I'm getting an exception while walking a file tree of a VFS (virtual file system) of a zip file using java nio, here is my code:

public static void list(String zipFilePath) throws IOException{
    FileSystem fs = FileSystems.newFileSystem(Paths.get(zipFilePath), null);
    Path startPath = fs.getPath("/");

    Files.walkFileTree(startPath, new SimpleFileVisitor<Path>() {
        @Override
        public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
            System.out.println("Dir : " + dir);
            return FileVisitResult.CONTINUE;
        }

        @Override
        public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
            System.out.println("\t->File : " + file);
            return FileVisitResult.CONTINUE;
        }
    });
}

the exception says that a file does not exists, but I've decompress the archive (zip), and the file is there... any idea why?

here is the exception:

java.nio.file.NoSuchFileException: /Dir1/Dir2/Dir3/Dir4/ExcelFile.xlsm
at com.sun.nio.zipfs.ZipPath.getAttributes(ZipPath.java:657)
at com.sun.nio.zipfs.ZipFileSystemProvider.readAttributes(ZipFileSystemProvider.java:285)
at java.nio.file.Files.readAttributes(Files.java:1669)
at java.nio.file.FileTreeWalker.walk(FileTreeWalker.java:105)
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:2585)
at java.nio.file.Files.walkFileTree(Files.java:2618)

BTW: The code DOES work, but it crash with certain files

¿Fue útil?

Solución

When you're using a ZipFileSystem it manages the paths as they where stored (remember that there are no folders inside a zip, just files, and each file is identified by its complete path name, up to the level of the directory selected to be zipped, therefore it is not "myTextFile.txt" inside the zip its named as "/Folder 1/Folder 2/myTextFile.txt"); Using Path always return the name using the "standard" file separator (*nix OS), but if your zip archive was stored using the windows file separator, it just fails, this does not happend if you use the same method to create your file that you will use to open, I mean, if you use ZipOutputStream and ZipEntry to compress your file, and then ZipFileSystem to decompress it, it fails if you are not careful with the file separators.

Now, you may say, why does it fails only with certain files inside the zip in your case then, well, when I was working with the software causing this problem, I was zipping the files using ZipOutputStream ZipEntry, and Path, I "manually" navigating through the file tree, until I reach a file, and to add a zip entry I was using Path and then adding to the String name the name of file to be saved adding a separator by concatenating it (+"/"+).

You may say "OK, I understand what you are saying, but, why in hell was it working when you decompress the archive using a third party software?", thats an easy one, it is because they replace all the file separators the could find in each file name to ensure they are using allways the same file separator, whether '/' or '\'...

Lessons Learned: DO NOT mix stuff!!! use one single method to compress and decompress your archives, or ENSURE that all the info is being stored under the same "name", ensure that you are using the exact same file separators every time.

Otros consejos

I know this is an old post but exactly this just happened to me. All my zipfiles are created by a third party, namely Microsoft Word. I cannot even catch the exception to find out which input file from the zip is causing the NoSuchFileException, because the Java compiler says:

NoSuchFileException cannot be resolved to a type

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top