I've created a Flowable (RxJava v3) that parses a file. I'd like it to support backpressure. This is important because the files can be quite large, and I don't want them to be loaded into memory at once. Here is my first attempt:
public Flowable<Byte> asFlowable(InputStream is) {
return Flowable.create(new FlowableOnSubscribe<Byte>() {
@Override
public void subscribe(FlowableEmitter<Byte> emitter) throws Exception {
try (DataInputStream inputStream = new DataInputStream(is)){
if (inputStream.readInt() != SOME_CONSTANT) {
throw new IllegalArgumentException("illegal file format");
}
if (inputStream.readInt() != SOME_OTHER_CONSTANT) {
throw new IllegalArgumentException("illegal file format");
}
final int numItems = inputStream.readInt();
for(int i = 0; i < numItems; i++) {
if(emitter.isCancelled()) {
return;
}
emitter.onNext(inputStream.readByte());
}
emitter.onComplete();
} catch (Exception e) {
emitter.onError(e);
}
}
}, BackpressureStrategy.BUFFER);
}
The reason I used Flowable.create
instead of Flowable.generate
is because I need to validate the file, and throw errors if some magic numbers at the beginning of the file are wrong or not found. This didn't fit well with the Flowable.generate
lambdas (but if you know of a better way please post it).
Ok let's assume the cold Flowable supported backpressure. Now I'd like to process it in a console-like application.
Question:
I want to request a new Byte from the Flowable and print it to console each time the user presses space (similar to what more
or less
do in Linux). What would the best way of doing it? I intend to observe the flowable directly in the public static void main
method, since I need to read and write using the console.
I've been reading the Backpressure section in RxJAva's Wiki and found this snippet:
someObservable.subscribe(new Subscriber<t>() {
@Override
public void onStart() {
request(1);
}
@Override
public void onCompleted() {
// gracefully handle sequence-complete
}
@Override
public void onError(Throwable e) {
// gracefully handle error
}
@Override
public void onNext(t n) {
// do something with the emitted item "n"
// request another item:
request(1);
}
});
But this confused me even more as the request
method doesn't seem to exist in RxJava 3.