如何在Java中以非阻塞方式列出目录中的文件?

How to list files in directory in a non-blocking manner in Java?

在目录中列出 "files" 在 Java 中使用 nio 包中的 Files 很简单:

Stream<Path> paths = Files.list(Path.of("<folder>"))

但是对 Files.list(..) 的调用正在阻塞。如何以非阻塞方式列出目录中的文件?

更新

"blocking" 我的意思是不阻塞 任何 线程,就像在响应式编程的上下文中一样。在我的例子中,我使用 project reactor from Spring 并且我有一个这样定义的方法:

public Flux<String> doStuffWithFilesInDirectory(String dir) {
    // Intellij complains that the call to "Files.list(..)" is inappropriate since it's a blocking call
    var fileStream = Files.list(Path.of(dir)); 
    return Flux.fromStream(fileStream). ..
}

如果您只想从调用线程异步 运行 Files.list,您可以在不查找 "alternative" 文件 API 的情况下执行此操作。

最基本的例子是:

Runnable lister = () -> {
    try {
        SomeReceivingClassOrInstance
            .someEventMethod(Files.list(Path.of("yourPath")));
    }
    catch (IOException ioe) {
        // TODO handle
        ioe.printStackTrace();
    }
};

然后您可以:

  • 实现一个方法,在接收端获取 Stream<Path> 并执行。
  • 从您希望异步启动操作的地方 new Thread(lister).start(); 异步调用您的 Runnable

请注意,对于 运行 异步操作,有很多替代方案和更多 elegant/higher 级别的示例。

这只是一个例子来证明您不需要真的需要进一步研究 nio API(例如 FileVisitor 等)来异步化它.

备注

事后思考:如果相反,您真的希望一个集合根据列表的内容逐渐填充 "discovers",那么您最好自己开始一个 FileVisitor线程,并为每个条目填充一个线程安全的集合。

磁盘的特性是它们不会立即产生信息。因此可能的 "non-blocking" 解决方案是

(a) 在单独的线程中同步阻塞执行,或者

(b) 使用某种通知机制(回调、Future 等)启动异步操作,告诉您它何时完成。

在后一种情况下,您不仅需要通过某些 Java 方法实现这一点,而且底层 OS 需要提供支持。由于并非所有系统都提供 "asynchronous readdir",我怀疑您也找不到 Java 接口。这是一般推理的论点,所以我可能错了 - 但我不会打赌。