[英]RxJava. Read file to observable
I am totally new to RxJava and reactive programming. 我是RxJava和反应式编程的新手。 I have an assignment where i must read file and store it to Observable. 我有一个作业,我必须读取文件并将其存储到Observable。 I have tried to make a Callable with BufferedReader inside and use Observable.fromCallable(), but it didn't work much. 我曾尝试在内部使用BufferedReader创建一个Callable,并使用Observable.fromCallable(),但它没有多大用处。
Could you please show me how can i do that? 你能告诉我我该怎么办?
I am using RxJava 2.0. 我正在使用RxJava 2.0。
A basic solution where I use a nested class FileObservableSource
to produce the data and then defer the creation of the Observable until an Observer subscribes: 一个基本的解决方案,我使用嵌套类FileObservableSource
生成数据,然后推迟创建Observable直到Observer订阅:
import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.Observer;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
public class StackOverflow {
public static void main(String[] args) {
final Observable<String> observable = Observable.defer(() -> new FileObservableSource("pom.xml"));
observable.subscribe(
line -> System.out.println("next line: " + line),
Throwable::printStackTrace,
() -> System.out.println("finished")
);
}
static class FileObservableSource implements ObservableSource<String> {
private final String filename;
FileObservableSource(String filename) {
this.filename = filename;
}
@Override
public void subscribe(Observer<? super String> observer) {
try {
Files.lines(Paths.get(filename)).forEach(observer::onNext);
observer.onComplete();
} catch (IOException e) {
observer.onError(e);
}
}
}
}
for Java 8, BufferedReader has a file stream and the iterator which you can use in tandem with RxJava. 对于Java 8,BufferedReader有一个文件流和迭代器,可以与RxJava一起使用。 https://dzone.com/articles/java-8-stream-rx-java https://dzone.com/articles/java-8-stream-rx-java
you can get a Flowable using the following code 您可以使用以下代码获取Flowable
Flowable.fromIterable(bufferedReader.lines()::iterator)
I use Flowable and Single to be more concise, it'll still work with Observable. 我使用Flowable和Single更简洁,它仍然适用于Observable。 the code snippet is an example of how I read each single line from the buffered reader. 代码片段是我如何从缓冲的阅读器中读取每一行的示例。
try (
FileReader fr = new FileReader("./folder1/source.txt");
BufferedReader br = new BufferedReader(fr);
//e.g. i write the output into this file
FileWriter fw = new FileWriter("./folder1/destination.txt");
BufferedWriter bw = new BufferedWriter(fw)
) {
//=========================================
//calling br.lines() gives you the stream.
//br.lines()::iterator returns you the iterable
//=========================================
Flowable.fromIterable(br.lines()::iterator)
//at this point you can do what you want for each line
//e.g. I split long strings into smaller Flowable<String> chunks.
.flatMap(i -> splitLine(i))
//e.g. I then use the output to query an external server with retrofit.
// which returns me a Single<String> result
.flatMapSingle(i -> handlePinyin(pr, i))
.subscribe(
//I save the results from server to destination.txt
py -> appendToFile(bw, py),
//print and quit if error
err -> print("ERROR " + err),
() -> print("Completed!"));
}catch (IOException e) {
print("Error " + e);
}
You can do something similar to this implementation . 您可以执行与此实现类似的操作。
And then that class is used here in this way: 然后将该类是用来在这里以这种方式:
public static Observable<byte[]> from(InputStream is, int size) {
return Observable.create(new OnSubscribeInputStream(is, size));
}
Eventually you can use it: 最终你可以使用它:
Observable<byte[]> chunks = Bytes.from(file, chunkSize);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.