https://github.com/javasync/rxio
Asynchronous non-blocking File Reader and Writer library for Java
https://github.com/javasync/rxio
asynchronous java java-nio non-blocking
Last synced: about 1 month ago
JSON representation
Asynchronous non-blocking File Reader and Writer library for Java
- Host: GitHub
- URL: https://github.com/javasync/rxio
- Owner: javasync
- License: mit
- Created: 2018-06-06T15:49:43.000Z (over 7 years ago)
- Default Branch: master
- Last Pushed: 2022-12-20T16:13:24.000Z (about 3 years ago)
- Last Synced: 2025-07-04T11:55:58.951Z (8 months ago)
- Topics: asynchronous, java, java-nio, non-blocking
- Language: Java
- Homepage:
- Size: 430 KB
- Stars: 30
- Watchers: 3
- Forks: 4
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# RxIo
[](https://sonarcloud.io/dashboard?id=com.github.javasync%3ARxIo)
[](https://sonarcloud.io/dashboard?id=com.github.javasync%3ARxIo)
[](https://search.maven.org/artifact/com.github.javasync/RxIo)
The [`AsyncFiles`](src/main/java/org/javaync/io/AsyncFiles.java) class allows JVM
applications to easily read/write files asynchronously with non-blocking IO.
`AsyncFiles` take advantage of Java [AsynchronousFileChannel](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/nio/channels/AsynchronousFileChannel.html)
to perform asynchronous I/O operations.
`AsyncFiles` provides equivalent operations to the standard JDK
[Files](https://docs.oracle.com/javase/10/docs/api/java/nio/file/Files.html)
class but using non-blocking IO and an asynchronous API with different
asynchronous idioms, namely:
`CompletableFuture`,
jayield [`AsyncQuery`](https://github.com/tinyield/jayield#internals-overview),
[reactive-streams](https://www.reactive-streams.org) [`Publisher`](https://www.reactive-streams.org/reactive-streams-1.0.3-javadoc/org/reactivestreams/Publisher.html),
Kotlin coroutines and Kotlin [Asynchronous Flow](https://kotlinlang.org/docs/flow.html).
In section [Usage](#Usage) we present some examples using the
[`AsyncFiles`](src/main/java/org/javaync/io/AsyncFiles.java)
class side by side with the corresponding blocking version of
[Files](https://docs.oracle.com/javase/10/docs/api/java/nio/file/Files.html).
## Installation
First, in order to include it to your project,
simply add this dependency:
Maven
Gradle
```xml
com.github.javasync
RxIo
1.2.5
```
```groovy
implementation 'com.github.javasync:RxIo:1.2.5'
```
## Usage
Kotlin examples:
```kotlin
suspend fun copyNio(from: String, to: String) {
val data = Path(from).readText() // suspension point
Path(to).writeText(data) // suspension point
}
```
```kotlin
fun copy(from: String, to: String) {
val data = File(from).readText()
File(to).writeText(data)
}
```
```kotlin
Path("input.txt")
.lines() // Flow
.onEach(::println)
.collect() // block if you want to wait for completion
```
```kotlin
Path("input.txt")
.readLines() // List
.forEach(::println)
```
Java examples:
```java
AsyncFiles
.readAllBytes("input.txt")
.thenCompose(bytes -> AsyncFiles.writeBytes("output.txt", bytes))
.join(); // block if you want to wait for completion
```
```java
Path in = Paths.get("input.txt");
Path out = Paths.get("output.txt");
byte[] bytes = Files.readAllBytes(in);
Files.write(out, bytes);
```
```java
AsyncFiles
.asyncQuery("input.txt")
.onNext((line, err) -> out.println(line)) // lack check err
.blockingSubscribe(); // block if you want to wait for completion
```
```java
Path path = Paths.get("input.txt");
Files
.lines(path)
.forEach(out::println)
```
```java
List data = asList("super", "brave", "isel", "gain");
AsyncFiles
.write("output.txt", data) // writing lines to output.txt
.join(); // block if you want to wait for completion
```
```java
List data = asList("super", "brave", "isel", "gain");
Path path = Paths.get("output.txt")
Files.write(path, data);
```
The [`AsyncFiles::lines()`](src/main/java/org/javaync/io/AsyncFiles.java#L84)
returns a reactive [`Publisher`](https://www.reactive-streams.org/reactive-streams-1.0.0-javadoc/org/reactivestreams/Publisher.html)
which is compatible with Reactor or RxJava streams.
Thus we can use the utility methods of Reactor [`Flux`](https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Flux.html)
to easily operate on the result of `AsyncFiles::lines()`.
In the following example we show how to print all words of a gutenberg.org file content without repetitions:
```java
Flux
.from(AsyncFiles.lines(file))
.filter(line -> !line.isEmpty()) // Skip empty lines
.skip(14) // Skip gutenberg header
.takeWhile(line -> !line.contains("*** END OF ")) // Skip gutenberg footnote
.flatMap(line -> Flux.fromArray(line.split("\\W+")))
.distinct()
.doOnNext(out::println)
.doOnError(Throwable::printStackTrace)
.blockLast(); // block if you want to wait for completion
```
Alternatively, the [`AsyncFiles::asyncQuery()`](src/main/java/org/javaync/io/AsyncFiles.java#L60)
returns an `AsyncQuery` that allows asynchronous subscription and chaining intermediate operations
such as `filter`, `map` and others.
We can rewrite the previous sample as:
```java
AsyncFiles
.asyncQuery(file)
.filter(line -> !line.isEmpty()) // Skip empty lines
.skip(14) // Skip gutenberg header
.takeWhile(line -> !line.contains("*** END OF ")) // Skip gutenberg footnote
.flatMapMerge(line -> AsyncQuery.of(line.split("\\W+")))
.distinct()
.subscribe((word, err) -> {
if(err != null) err.printStackTrace();
else out.println(word);
})
.join(); // block if you want to wait for completion
```