【发布时间】: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