我正在为我的磁盘上可能存在的文件提供下载功能。这是在播放/斯卡拉。我有以下下载方法,给我文件。但我想使用ZipOutputstream
并发送文件。我不想先在磁盘上压缩文件,然后再进行压缩。我不知道如何实现它。此外,在这种情况下,长度参数是什么样的?
def downloadLocalBackup() = Action {
var pathOfFile = "/opt/mycompany/backups/mydir/backup"
val file = new java.io.File(pathOfFile)
val path: java.nio.file.Path = file.toPath
val source: Source[ByteString, _] = FileIO.fromPath(path)
Ok.sendEntity(HttpEntity.Streamed(source,None, Some("file"))).withHeaders("Content-Disposition"->s"attachment; filename=backup")
}
编辑我的帖子并添加我写的代码,但我不高兴我必须将zip文件读入zip流。我认为这没有优化?
def downloadLocalBackup2() = Action {
var pathOfFile = "/opt/mycompany/backups/backupdir/backup"
val file = new java.io.File(pathOfFile)
val path: java.nio.file.Path = file.toPath
val enumerator = Enumerator.outputStream { os =>
val zipStream = new ZipOutputStream(os)
zipStream.putNextEntry(new ZipEntry("backup2"))
val is = new BufferedInputStream(new FileInputStream(pathOfFile))
val buf = new Array[Byte](1024)
var len = is.read(buf)
while (len >= 0) {
zipStream.write(buf, 0 ,len)
len = is.read(buf)
}
is.close
zipStream.close()
}
val kk = Ok.sendEntity(HttpEntity.Streamed(Source.fromPublisher(Streams.enumeratorToPublisher(enumerator)).map(x=>{val kk = Writeable.wByteArray.transform(x);kk}),
None, Some("application/zip"))
).withHeaders("Content-Disposition" -> s"attachment; filename=backupfile.zip")
kk
}
答案 0 :(得分:0)
在这种情况下,您可以使用GZIPOutputStream:
import java.io.ByteArrayOutputStream
import java.util.zip.GZIPOutputStream
val txt = "text to zip"
val arrOutputStream = new ByteArrayOutputStream()
val zipOutputStream = new GZIPOutputStream(arrOutputStream)
zipOutputStream.write(txt.getBytes)
zipOutputStream.close()
val result: Array[Byte] = arrOutputStream.toByteArray
答案 1 :(得分:0)
您可以使用Compression
对ZipOutputStream
的流进行gzip压缩,而不是使用ByteString
:
val source: Source[ByteString, _] =
FileIO.fromPath(path)
.via(Compression.gzip)
您需要一个能够使用相应的Compression.gunzip()
来处理压缩数据流的消费者。
对于contentLength
,明确提供它而不是使用None
(如果将其保留为None
,Play会将整个文件加载到内存中以计算长度):< / p>
val contentLength = Some(file.length)
Ok.sendEntity(HttpEntity.Streamed(source, contentLength, Some("file"))).withHeaders("Content-Disposition" -> s"attachment; filename=backup")