如何在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 接口。这是一般推理的论点,所以我可能错了 - 但我不会打赌。
在目录中列出 "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 接口。这是一般推理的论点,所以我可能错了 - 但我不会打赌。