如何从RxJava中的输入流创建Observable字节序列

时间:2016-06-24 16:02:06

标签: java rx-java

我是RxJava的新手,因此,问这个问题。我有一个输入流,我必须转换为特定大小的字节数组序列。类似的东西:

Observable
  .just(inputStream)
  .map(new Func1<InputStream, Chunk>());

此处Chunk是一个自定义类,其中包含从流中读取的字节数。有人可以帮我理解如何在RxJava中执行此操作

2 个答案:

答案 0 :(得分:3)

使用RxJavaString中的StringObservable.from(InputStream, chunkSize)。它将返回Observable<byte[]>并支持背压(除非下游请求,否则不会从InputStream读取。)

顺便说一句,Observable.using完成了正确关闭资源的图片。如果您正在从文件中读取字节(在封面下使用Bytes.from(file, chunkSize)),则可以使用rxjava-extras中的Observable.using

答案 1 :(得分:1)

您可以使用Observable.create,然后使用flatMap。请注意,默认情况下,QueuedProducer是无限制的,您可以提供包含边界队列的自定义实现。

例如:

  static class Chunk {
    byte[] buf;
    int size;
    int index;
    public Chunk(byte[] buf, int size, int index) {
      this.buf = buf;
      this.size = size;
      this.index = index;
    }

  }

  FileInputStream fis = ...
  Observable<Chunk> o = Observable.just(fis).flatMap(new Func1<InputStream, Observable<Chunk>>() {

  @Override
  public Observable<Chunk> call(InputStream is) {
    return Observable.create(new Observable.OnSubscribe<Chunk>() {

      public void call(Subscriber<? super Chunk> subscriber) {
        final QueuedProducer<Chunk> producer = new QueuedProducer<>(subscriber);
        subscriber.setProducer(producer);
        try {
          int size = 0;
          int index = 0;
          do {
            byte[] buf = new byte[4096];
            size = is.read(buf);
            if (size > 0) {
              Chunk chunk = new Chunk(buf, size, index++);
              System.out.println("Producing chunk #" + index + " of size: " + chunk.size);
              producer.onNext(chunk);
            }
          } while (size >= 0);
          producer.onCompleted();
        } catch (IOException e) {
          producer.onError(e);
        } finally {
          try {
            System.out.println("Closing stream");
            is.close();
          } catch (IOException e) {
          }
        }
      }
    })
    .subscribeOn(Schedulers.io());
 }
});

o.subscribe(new Action1<Chunk>() {

  @Override
  public void call(Chunk chunk) {
    System.out.println("Received chunk #" + chunk.index + " of size: " + chunk.size);

  }

});

Thread.sleep(10000);