我需要使用java.util.zip.ZipOutputStream
来回复压缩文件存档。
数据是几百兆字节未压缩,所以我想尽可能少地存储。它来自SQL结果的序列化。
我看到使用OutputStream
使用Enumerator.outputStream
返回分块结果的示例:
但是当我阅读文档(强调我的)时,这些似乎是不明智的
显然,我无法使用它。或者至少没有修改。使用OutputStream创建一个字节的枚举器。
写入的调用不会阻塞,所以如果被输入的iteratee使用输入的速度很慢,那么 OutputStream不会回推。这意味着它不应该用于大流,因为存在风险 内存不足。
如何使用OutputStream
创建响应(在这种情况下,是一个gzip压缩文件),同时确保只有部分内容存储在内存中?
我认识到InputStream
s / OutputStream
和Play Enumerator
/ Iteratee
范例之间的区别,所以我希望我需要一种特定的方式生成我的源数据(SQL结果的序列化),使其不超过下载速度。我不知道它是什么。
答案 0 :(得分:4)
一般情况下,您无法安全地将任何OutputStream
与Enumerator / Iteratee框架一起使用,因为OutputStream
不支持非阻止回退。但是,如果你可以控制对OutputStream
的写作,你可以将这些内容整合起来:
val baos = new ByteArrayOutputStream
val zos = new ZipOutputStream(baos)
val enumerator = Enumerator.generateM {
Future.successful {
if (moreDateToWrite) {
// Write data into zos
val r = Some(baos.toByteArray)
baos.reset()
r
} else None
}
}
如果您只需要压缩,请查看Enumeratee
和play.filters.gzip.Gzip
过滤器中提供的play.filters.gzip.GzipFilter
个实例。
答案 1 :(得分:0)
ViewDidLoad()
唯一的反压机制是阻塞线程。所以,不管怎样,必须有一个能够被阻止的线程。
一种方法是使用管道流。
Unable to bind: source property source not found IndexedProperty:0 on String[]
由于操作阻塞,您必须注意防止死锁。
使用两个不同的线程池,或使用缓存(无界)线程池。