Scala 使用play framework 2.3动态下载归档文件
我正在尝试在不依赖内存的情况下创建和下载存档文件(以避免大文件出现内存不足异常),我正在使用Scala的play framework 2.3,经过一些研究后,我发现了一个示例:,我对其进行了一些修改。我的问题是,当我下载文件并尝试打开它时,会出现以下异常:加载存档文件时出错。 以下是所有代码:Scala 使用play framework 2.3动态下载归档文件,scala,zip,streaming,playframework-2.3,archive-file,Scala,Zip,Streaming,Playframework 2.3,Archive File,我正在尝试在不依赖内存的情况下创建和下载存档文件(以避免大文件出现内存不足异常),我正在使用Scala的play framework 2.3,经过一些研究后,我发现了一个示例:,我对其进行了一些修改。我的问题是,当我下载文件并尝试打开它时,会出现以下异常:加载存档文件时出错。 以下是所有代码: def zip() = Action { implicit request: Request[AnyContent] => val buffer = new ZipBuff
def zip() = Action {
implicit request: Request[AnyContent] =>
val buffer = new ZipBuffer(10000)
val writeCentralDirectory = Enumerator.generateM(Future{
if (buffer.isClosed) {
None
}
else {
buffer.flush
buffer.close
Some(buffer.bytes)
}
})
val test = Enumerator.apply(ResolvedSource2("test.txt", "helllo"))
Ok.chunked(test &> zipeach2(buffer) andThen writeCentralDirectory >>> Enumerator.eof) as withCharset("application/zip") withHeaders(
CONTENT_DISPOSITION -> s"attachment; filename=aa.zip")
}
case class ResolvedSource2(filepath: String, stream: String)
def zipeach2(buffer: ZipBuffer)(implicit ec: ExecutionContext): Enumeratee[ResolvedSource2, Array[Byte]] = {
Enumeratee.mapConcat[ResolvedSource2] { source =>
buffer.zipStream.putNextEntry(new ZipEntry(source.filepath))
var done = false
def entryDone: Unit = {
done = true
buffer.zipStream.closeEntry
}
def restOfStream: Stream[Array[Byte]] = {
if (done) Stream.empty
else {
while (!done && !buffer.full) {
try {
val byte = source.stream
buffer.zipStream.write(byte.getBytes)
entryDone
}
catch {
case e: IOException =>
println(s"reading/zipping stream [${source.filepath}]", e)
}
}
buffer.bytes #:: restOfStream
}
}
restOfStream
}
}
}
class ZipBuffer(capacity: Int) {
private val buf = new ByteArrayOutputStream(capacity)
private var closed = false
val zipStream = new ZipOutputStream(buf)
def close(): Unit = {
if (!closed) {
closed = true
reset
zipStream.finish()
zipStream.close // writes central directory
}
}
def flush() = {
zipStream.flush()
}
def isClosed = closed
def reset: Unit = buf.reset
def full: Boolean = buf.size >= capacity
def bytes: Array[Byte] = {
val result = buf.toByteArray
reset
result
}
}