'Read file line by line using non-blocking IO with reactive wrapper in Java
Is there any way to read a local file line by line without blocking any thread (background thread pool counts as blocking) using built-in CompletableFuture or a reactive stream library like RxJava or Reactor?
(It's interesting that there are many non-blocking IO libraries for HTTP and different databases like Mongo, Redis, etc., but I wasn't able to find anything for a simple file read.)
Solution 1:[1]
Although, I got answer for my question from Alexander, I'd like to share the most reactive ways that I found to read a file line by line. Both solutions use AsynchronousFileChannel under the hood which is not always non-blocking but still okay to use in a reactive environment since it uses a dedicated thread pool for IO work.
Using utils from Spring Framework (ideal in WebFlux application)
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));
}
}
Using RxIo library
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")));
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Martin Tarjányi |
