[英]Non-blocking reading from the file using Reactor
Do you know if it's possible to create Flux of file lines really non-blocking way?你知道是否有可能以非阻塞方式创建文件行的 Flux 吗?
The best solution I've found is next:我找到的最佳解决方案是下一个:
Flux.using(
() -> Files.lines(PATH),
Flux::fromStream,
Stream::close
);
Even though it looks non-blocking but it is blocking under the hood.即使它看起来没有阻塞,但它在引擎盖下是阻塞的。
https://docs.oracle.com/javase/8/docs/api/java/nio/file/Files.html#lines-java.nio.file.Path-java.nio.charset.Charset- https://docs.oracle.com/javase/8/docs/api/java/nio/file/Files.html#lines-java.nio.file.Path-java.nio.charset.Charset-
Read all lines from a file as a Stream.
从文件中读取所有行作为 Stream。 Unlike readAllLines, this method does not read all lines into a List, but instead populates lazily as the stream is consumed.
与 readAllLines 不同,此方法不会将所有行读入 List,而是在 stream 被消耗时延迟填充。
The returned stream encapsulates a Reader.
返回的 stream 封装了一个 Reader。
Is it possible to create Flux from AsynchronousFileChannel?是否可以从 AsynchronousFileChannel 创建 Flux?
Thank you in advance先感谢您
Files.lines(PATH)
is completely IO-free. Files.lines(PATH)
完全没有 IO。 It's part of the NIO (NIO stands for non-blocking I/O or New I/O) Java API.它是 NIO 的一部分(NIO 代表非阻塞 I/O 或新 I/O)Java API。 It lazily returns a stream of lines, which is part of
.util
package and not .io
package like BufferedReader
. It lazily returns a stream of lines, which is part of
.util
package and not .io
package like BufferedReader
.
If you have Spring Framework on classpath, then you can do the following:如果您在类路径上有 Spring 框架,那么您可以执行以下操作:
import org.springframework.core.codec.StringDecoder;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.core.io.buffer.DefaultDataBufferFactory;
import java.nio.channels.AsynchronousFileChannel;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
public class AsyncFileRead {
public static void main(String[] args) {
StringDecoder stringDecoder = StringDecoder.textPlainOnly();
DataBufferUtils.readAsynchronousFileChannel(() -> AsynchronousFileChannel.open(Path.of("test/sample.txt"),
StandardOpenOption.READ), DefaultDataBufferFactory.sharedInstance, 4096)
.transform(dataBufferFlux -> stringDecoder.decode(dataBufferFlux, null, null, null))
.blockLast();
}
}
Alternatively, you can use RxIo library which provides a nice abstraction similar to java.nio.file.Files
just with async/reactive support:或者,您可以使用RxIo库,它提供了类似于
java.nio.file.Files
的漂亮抽象,仅支持异步/反应式:
import org.javaync.io.AsyncFiles;
import reactor.core.publisher.Flux;
import java.nio.file.Path;
public class AsyncFileRead {
public static void main(String[] args) {
Flux.from(AsyncFiles.lines(Path.of("test/sample.txt")))
.blockLast();
}
}
Although, it's important to note that even these solutions are not truly non-blocking as depending on the platform (Windows, Linux) AsynchronousFileChannel
implementation can be blocking under the hood but at least it delegates that task to a dedicated thread pool.虽然,重要的是要注意,即使这些解决方案也不是真正的非阻塞,因为取决于平台(Windows、Linux),
AsynchronousFileChannel
实现可能在后台阻塞,但至少它将该任务委托给专用线程池。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.