scala – 使用Spray发送大文件

我知道之前曾提出过非常类似的问题.但我认为我在google / stackoverflow上找到的解决方案并不适合我.

我开始用Scala / Spray编写一些Web服务,似乎在不消耗大量内存的情况下发送大型文件的最佳方法是使用流编组.这种方式Spray将发送http块.两个问题:

>是否可以在不使用HTTP块的情况下发送文件,而无需将整个文件读入内存?
> AFAIK akka.io一次只处理一次写入,这意味着它可以缓冲一次写入,直到它完全传递给O / S内核.是否有可能告诉Spray每个HTTP响应的内容长度?此后,Spray将要求新数据(通过akka消息),直到完成整个内容长度.例如,我指出我的内容长度是100个字节. Spray向我的actor发送一条消息,要求提供数据,我提供了50个字节.一旦将此数据传递给操作系统,喷涂就会发送另一条消息,要求提供新数据.我提供剩余的50个字节……然后完成响应.

最佳答案

Is it possible to send the file without using HTTP chunks [on the wire]

是的,您需要启用无块流式传输.见http://spray.io/documentation/1.2.4/spray-routing/advanced-topics/response-streaming/

无论您是使用Stream marshaller还是自己提供MessageChunks响应,无块流式传输都能正常工作.请参阅以下示例.

without reading the entire file into memory

是的,如果您以Stream [Array [Byte]]或Stream [ByteString]的形式提供数据,这应该可行.

[…] Thereafter Spray would ask for new data […]

这实际上几乎就像它已经有效一样:如果您手动提供块,您可以请求自定义Ack消息,当喷涂层能够处理下一部分时,该消息将被传递给您.有关如何从喷射路线流动,请参见this example.

I indicate my content length is 100 bytes

提前注意:在HTTP中,您不需要为响应指定内容长度,因为可以通过关闭连接来定界响应主体,如果启用了无块流,则喷涂会执行此操作.但是,如果您不想关闭连接(因为您将丢失此持久连接),现在可以在ChunkedResponseStart消息中指定显式的Content-Length标头(请参阅#802),这将阻止关闭连接.

点赞