【问题标题】:Write to Zip File System with other fs open在其他 fs 打开的情况下写入 Zip 文件系统
【发布时间】:2014-10-27 11:10:17
【问题描述】:

我想要一个静态 Path 属性来扫描子文件,这个 Path 引用了一个 zip 文件,我无法关闭它,因为它会被随机引用。在某些时候,我需要写入 zip 文件。问题是我不想关闭文件系统,因为 Path 属性需要打开以供将来阅读,如果我不关闭它,我就看不到写入的更改。如果我尝试创建另一个引用相同路径的文件系统,我会得到 FileSystemAlreadyExistsException。我可以在写入后关闭 fs 然后再次打开它,但此时有人可能会尝试读取路径。 有解决方法吗?为什么我不需要关闭默认文件系统来查看写入的文件,而我确实需要使用 zip 文件系统?

    public static void copyTree(final Path source, final Path targetPath) throws IOException {
        FileSystem fs = FileSystems.getFileSystem(targetPath.toUri());

        Files.walkFileTree(source, new SimpleFileVisitor<Path>() {
            @Override
            public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
                Files.copy(dir, targetPath, StandardCopyOption.REPLACE_EXISTING);
                return super.preVisitDirectory(dir, attrs);
            }
            @Override
            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                Files.copy(file, targetPath, StandardCopyOption.REPLACE_EXISTING);
                return super.visitFile(file, attrs);
            }

        });

        //if I don't close the FileSystem here the changes won't appear.
        fs.close();
    }

【问题讨论】:

  • fs 在您的示例中完全没用,除了close 之外,它什么也不做,也没有被任何东西使用 - 基本上,您打开一个文件并再次关闭它而不明确阅读它。跨度>

标签: java concurrency java-7 nio


【解决方案1】:

你没有关闭“文件系统”,你可以关闭一个文件——这些是完全不同的东西。 FileSystemAlreadyExistsException 简直是名不副实 - 不能完全用 java 关闭/卸载文件系统,AFAIK,请停止使用“文件系统”这个词来表示文件,它非常令人困惑。

回答您的问题:如果我设法正确解读它,您想知道从多个线程访问一个文件,这是否正确?

在这种情况下,最简单的解决方案是:将对文件的访问包装到一个新类中,使该类成为singleton 和每个写入方法synchronized。这样每个写操作都会阻塞,直到最后一个完成 - 使用关闭文件的附加方法,您甚至可以以受控方式关闭应用程序:http://docs.oracle.com/javase/7/docs/api/java/io/Closeable.html,您也可以使用 try-with-resources 进行 nio 方法调用抛出异常

我认为这个 .property 文件的小例子可能带有这个想法:Load Properties File in Singleton Class

【讨论】:

  • 感谢您的回答,很抱歉造成混乱。我说的是关闭 FileSystem 对象,而不是文件,我用一些代码更新了问题以便更好地解释。
  • 我可以同步所有写入文件系统的方法,但问题是我还需要同步读取方法,因为我需要在写入 fs 对象后立即关闭它。
  • ...是的,这几乎就是您需要做的。事实上,建议您在每次读取操作开始时锁定整个文件,并且仅在再次写入/关闭文件后解锁 - 这是避免竞争条件的唯一方法。我建议使用信号量 - 这些非常有效且易于使用。
  • 我必须重新创建文件系统才能检查目录是否为空?如果它们也在同一个 fs 中,我将不得不同步对不同文件的访问..
  • 你没有关闭“文件系统”:我不同意。事实上FileSystem.close() 需要 调用ZipFileSystem 否则将来打开相同的jar 文件将导致FileSystemAlreadyExistsException
猜你喜欢
  • 1970-01-01
  • 2020-11-09
  • 2020-09-30
  • 2020-04-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多