【问题标题】:nosuchfileexception while walking files tree inside a zip using java nio使用java nio在zip中行走文件树时出现nosuchfileexception
【发布时间】:2013-02-01 20:48:13
【问题描述】:

我在使用 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;
        }
    });
}

异常表明文件不存在,但我已解压缩存档 (zip),并且文件在那里...知道为什么吗?

这里是个例外:

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)

顺便说一句:代码确实可以工作,但它会因某些文件而崩溃

【问题讨论】:

  • 它失败的文件是否有任何模式?总是xlsm?压缩文件中使用的任何密码?
  • 不,不,我至少可以看到...
  • 你有没有想过这个问题?我也很难过。从stackoverflow.com/questions/14436032/… cmets 我目前的猜测是它正在调用某种本机窗口 getAttributes in error 或什么...jdk 错误? jdk错误只是在Windows上?你在窗户上吗?
  • 是的,让我添加我的答案,谢谢你提醒我这个

标签: java zip nio virtualfilesystem


【解决方案1】:

当您使用ZipFileSystem 时,它会管理存储路径(请记住,zip 中没有文件夹,只有文件,每个文件都由其完整路径名标识,最高级别为选择要压缩的目录,因此它不是压缩包内的“myTextFile.txt”,其命名为“/Folder 1/Folder 2/myTextFile.txt”);使用Path always 使用“标准”文件分隔符(*nix OS)返回名称,但如果您的 zip 存档是使用 windows 文件分隔符存储的,它只会失败,如果您使用相同的方法创建您将用来打开的文件,我的意思是,如果您使用ZipOutputStreamZipEntry 压缩文件,然后使用ZipFileSystem 解压缩它,如果您不小心它会失败使用文件分隔符。

现在,您可能会说,在您的情况下,为什么只有 zip 中的某些文件才会失败,那么,当我使用导致此问题的软件时,我正在使用 ZipOutputStream ZipEntry 压缩文件和Path,我“手动”浏览文件树,直到找到一个文件,然后添加一个我使用Path 的zip 条目,然后在String 名称中添加要保存的文件的名称通过连接来添加分隔符 (+"/"+)。

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

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

【讨论】:

  • 我在做Files.walk(root, 1).filter(...).findAny()(其中root 是来自ZIP 文件系统的目录)并得到java.io.UncheckedIOException: java.nio.file.NoSuchFileException。事实证明,原因是 ZIP 文件中的文件名中的反斜杠。这个问题和答案真的帮助了我——在被问到四年后:)
  • "不要混用东西" 但是如果我必须处理第三方 zips 文件怎么办?
  • 你需要适应你的逻辑来处理这两种斜线类型,我会获得 zip 文件中的文件列表。让我们假设最初创建文件的人是个白痴,并决定将文件存储为\folder1/folder2/folder3\myfile.txt;这是一个可怕的混乱,但为了轻松处理这种情况,我要做的是创建一个包含 "pretty" 名称的 map 并指向糟糕的名称,对于前面的示例,/folder1/folder2/folder3/myfile.txt 应该指向 \folder1/folder2/folder3\myfile.txt
  • 遇到了类似的问题 "+ File.separator +" help java.io.FIles
  • @SDV 你应该检查this other question 我问过,我已经走这条路了,File.separator 是系统相关的,而 zip 文件规范清楚地定义了 zip 中的正确分隔符
【解决方案2】:

我知道这是一篇旧帖子,但这恰好发生在我身上。 我所有的 zipfile 都是由第三方创建的,即 Microsoft Word。 我什至无法捕获异常以找出 zip 中的哪个输入文件导致 NoSuchFileException,因为 Java 编译器说:

NoSuchFileException 无法解析为类型

【讨论】:

  • 嗨,如果人们还在阅读它,那不是旧帖子;) 尝试导入该异常,它应该存在,因为它是 Java SE 的一部分:import java.nio.file.NoSuchFileException; 提示:也许你被否决了因为这可能是一个更好的评论
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-29
  • 2021-09-02
  • 2018-08-13
  • 2017-10-19
相关资源
最近更新 更多