【问题标题】:Creating a Java InputStream from an Enumerator[Array[Byte]]从 Enumerator[Array[Byte]] 创建 Java InputStream
【发布时间】:2015-03-16 15:41:38
【问题描述】:

为了在我的应用程序中实现一个新模块,我已经阅读了很多关于 Iteratees 和 Enumerators 的内容。

我现在正处于与第 3 方 Java 库集成的阶段,并且一直坚持使用这种方法:

public Email addAttachment(String name, InputStream file) throws IOException {
    this.attachments.put(name, file);
    return this;
}

我的 API 中的内容是从 WS HTTP 调用返回的主体,即 Enumerator[Array[Byte]]

我现在想知道如何编写一个Iteratee 来处理Array[Bytes] 的块并创建一个InputStream 以在此方法中使用。

(侧栏):还有其他版本的 addAttachment 方法采用 java.io.File 但是我想避免在此操作中写入磁盘,而宁愿处理流。

我试图从写这样的东西开始:

Iteratee.foreach[Array[Byte]] { bytes =>
    ???
}

但是我不确定如何在这里与 java InputStream 交互。我发现了一个叫做 ByteArrayInputStream 的东西,但是它在它的构造函数中使用了整个 Array[Byte],我不确定在这种情况下它是否可以工作,因为我正在使用块?

我可能需要一些 Java 帮助!

提前感谢您的帮助。

【问题讨论】:

  • 这是一个困难的。我认为您最好的选择是使用底层枚举器创建 InputStream 接口的实现。然后在每个 read 调用中,从 Enumerator 消耗必要数量的字节。
  • 除此之外,我认为您最好的选择是缓存所有内容并将其输入到 ByteArrayInputStream。问题是,Enumerator 是具有推送机制的数据流,而 InputStream 使用拉取机制,这意味着您需要在某处有一个缓冲区,否则这将无法正常工作。您现在可以缓冲所有内容,也许稍后再决定当性能成为瓶颈时该怎么做。也许做部分缓冲区,你明白了。
  • 我还没有对此进行测试,但我尝试了这样的事情:val consume = body |>>> Iteratee.consume[Array[Byte]]() 然后new ByteArrayInputStream(consume) 稍后。我认为这是您第二条评论的幼稚实现,但是没有缓冲。
  • 我可以看看今晚晚些时候我能不能把东西放在一起。我不知道这个 WS api 会持续多久。听说 Akka 流即将在 Play 中实现。
  • 我也会尝试一下。我正在调用我自己的生成 PDF 文档的服务,然后通过 http 将它们拉出来。哦,所以他们打算从 WS api 中删除“getStream”?

标签: java scala playframework io iterate


【解决方案1】:

如果我关注你,我认为你想使用 PipedInputStream 和 PipedOutputStream:

https://docs.oracle.com/javase/8/docs/api/java/io/PipedInputStream.html

您总是成对使用它们。您可以像这样构造这对:

PipedInputStream in = new PipedInputStream(); //can also specify a buffer size
PipedOutputStream out = new PipedOutputSream(in);

将输入流传递给 API,然后在您自己的代码中遍历您的卡盘并写入您的字节。

唯一需要注意的是,您需要在单独的线程中读取/写入。在您的情况下,在单独的线程中进行迭代/编写可能会很好。我相信你在 Scala 中比我处理得更好,在 Java 中它会是这样的:

PipedInputStream in = new PipedInputStream(); //can also specify a buffer size
PipedOutputStream out = new PipedOutputSream(out);
new Thread(() -> {
  // do your looping in here, write to 'out'
  out.close();
}).run();
email.addAttachment(in);
email.send();
in.close();

(为了清楚起见,省略了异常处理和资源处理)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-18
    相关资源
    最近更新 更多