使用java nio在zip中遍历文件树时出现nosuchfileexception

使用java nio在zip中遍历文件树时出现nosuchfileexception,java,zip,nio,virtualfilesystem,Java,Zip,Nio,Virtualfilesystem,我在使用java nio浏览zip文件的VFS(虚拟文件系统)文件树时遇到异常,下面是我的代码: public static void list(String zipFilePath) throws IOException{ FileSystem fs = FileSystems.newFileSystem(Paths.get(zipFilePath), null); Path startPath = fs.getPath("/"); Files.walkFileTre

我在使用java nio浏览zip文件的VFS(虚拟文件系统)文件树时遇到异常,下面是我的代码:

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;
        }
    });
}

顺便说一句:代码确实有效,但当您使用
ZipFileSystem
时,它会与某些文件崩溃。它会按照路径的存储位置管理路径(请记住,zip中没有文件夹,只有文件,每个文件都由其完整的路径名标识,直到选定要压缩的目录级别,因此它不是zip文件中的“myTextFile.txt”名为“/文件夹1/文件夹2/myTextFile.txt”);使用
路径
始终使用“标准”文件分隔符(*nix OS)返回名称,但如果使用windows文件分隔符存储zip存档文件,则会失败。如果使用与打开文件相同的方法创建文件,则不会发生这种情况。我的意思是,如果使用
ZipOutStream
ZipPentry
压缩文件,然后使用
ZipFileSystem
解压缩文件,则会失败不小心使用文件分隔符

现在,你可能会说,在你的情况下,为什么只有zip中的某些文件才会失败呢?那么,当我使用导致此问题的软件时,我使用
ZipOutputStream
ZipEntry
,和
Path
,I>手动压缩文件“在文件树中导航,直到我找到一个文件,要添加一个zip条目,我使用了
路径
,然后将要保存的文件名添加到
字符串
名称中,并通过连接它添加一个分隔符(
+“/”+

你可能会说“好吧,我明白你的意思,但是,当你使用第三方软件解压归档文件时,它到底为什么会起作用?”这很简单,因为它们会替换每个文件名中的所有文件分隔符,以确保它们始终使用相同的文件分隔符,无论是“/”还是“\”


经验教训:不要混搭东西!!!使用一种方法压缩和解压缩您的档案,或确保所有信息都存储在同一个“名称”下,确保每次使用完全相同的文件分隔符。

文件有任何模式失败吗?总是xlsm?zip文件中有密码吗?没有,没有,至少我能看到…你知道吗?我也被难倒了。从评论中,我目前的猜测是,它在错误地调用某种本机windows getAttributes或其他东西……jdk bug?windows上的jdk bug?你在windows上吗?是的,让我添加我的答案,谢谢你提醒我这一次我在做
文件.walk(root,1).filter(…).findAny()
(其中
root
是ZIP文件系统中的目录)并获得
java.io.UncheckedIOException:java.nio.file.NoSuchFileException
。结果证明,原因是ZIP文件中的文件名出现反斜杠。这个问题和答案真的帮助了我——在被问到四年后:)“不要混合东西”,但是如果我必须处理第三方zip文件呢?你需要调整你的逻辑来处理这两种斜杠类型,我将获得zip文件上的文件列表。让我们想象一下,最初创建该文件的人是个白痴,并决定将该文件存储为
\folder1/folder2/folder3\myfile.txt
;这是一个可怕的混乱,但为了轻松处理这种情况,我要做的是创建一个包含“漂亮”名称的映射,并指向糟糕的名称,因为前面的示例
/folder1/folder2/folder3/myfile.txt
应该指向
\folder1/folder2/folder3\myfile.txt
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)