If you have Spring Framework on classpath, then you can do the following:
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:
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.