簡體   English   中英

使用非阻塞 IO 和 Java 中的反應包裝逐行讀取文件

[英]Read file line by line using non-blocking IO with reactive wrapper in Java

有沒有什么方法可以使用內置的 CompletableFuture 或反應式 stream 庫(如 RxJava 或 Reactor)逐行讀取本地文件而不阻塞任何線程(后台線程池算作阻塞)

(有趣的是,有許多非阻塞 IO 庫用於 HTTP 和不同的數據庫,如 Mongo、Redis 等,但我無法找到任何用於簡單文件讀取的內容。)

盡管我從 Alexander 那里得到了問題的答案,但我還是想分享我發現的逐行讀取文件的最具反應性的方法。 這兩種解決方案都在底層使用AsynchronousFileChannel ,它並不總是非阻塞的,但仍然可以在反應性環境中使用,因為它使用專用線程池進行 IO 工作。

使用來自 Spring Framework 的實用程序(WebFlux 應用程序中的理想選擇)

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 Flux<String> lines() {
        StringDecoder stringDecoder = StringDecoder.textPlainOnly();

        return DataBufferUtils.readAsynchronousFileChannel(() -> AsynchronousFileChannel.open(Path.of("test/sample.txt"),
                StandardOpenOption.READ), DefaultDataBufferFactory.sharedInstance, 4096)
            .transform(dataBufferFlux -> stringDecoder.decode(dataBufferFlux, null, null, null));
    }
}

使用RxIo

import org.javaync.io.AsyncFiles;
import reactor.core.publisher.Flux;

import java.nio.file.Path;

public class AsyncFileRead {
    public Flux<String> lines() {
        return Flux.from(AsyncFiles.lines(Path.of("test/sample.txt")));
    }
}

有類似的問題:

Java 沒有通用的非阻塞文件 IO 的主要原因如下: Java 是一種跨平台語言,但 Unix 沒有非阻塞訪問文件。

如果您為 Windows 編程,則有一個特定於平台的實現WindowsAsynchronousFileChannelImpl ,它使用非阻塞機制。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM