簡體   English   中英

RxJava。 將文件讀取為可觀察的

[英]RxJava. Read file to observable

我是RxJava和反應式編程的新手。 我有一個作業,我必須讀取文件並將其存儲到Observable。 我曾嘗試在內部使用BufferedReader創建一個Callable,並使用Observable.fromCallable(),但它沒有多大用處。

你能告訴我我該怎么辦?

我正在使用RxJava 2.0。

一個基本的解決方案,我使用嵌套類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);
            }
        }
    }
}

對於Java 8,BufferedReader有一個文件流和迭代器,可以與RxJava一起使用。 https://dzone.com/articles/java-8-stream-rx-java

您可以使用以下代碼獲取Flowable

 Flowable.fromIterable(bufferedReader.lines()::iterator)

我使用Flowable和Single更簡潔,它仍然適用於Observable。 代碼片段是我如何從緩沖的閱讀器中讀取每一行的示例。

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);
}

您可以執行與此實現類似的操作。

然后將該類是用來在這里以這種方式:

public static Observable<byte[]> from(InputStream is, int size) {
     return Observable.create(new OnSubscribeInputStream(is, size));
}

最終你可以使用它:

Observable<byte[]> chunks = Bytes.from(file, chunkSize);

更多細節在這里

暫無
暫無

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

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