我知道之前曾提出过非常类似的问题。但我认为我在google / stackoverflow上找到的解决方案并不适合我。
我开始用Scala / Spray编写一些Web服务,似乎发送大文件而不消耗大量内存的最佳方法是使用流编组。这种方式Spray将发送http块。两个问题:
是否可以在不使用HTTP块而不将整个文件读入内存的情况下发送文件?
AFAIK akka.io一次只处理一次写入,这意味着它可以缓冲一次写入,直到它被完整地传递给O / S内核。是否有可能告诉Spray每个HTTP响应的内容长度?此后,Spray将要求新数据(通过akka消息),直到完成整个内容长度。例如,我指出我的内容长度是100个字节。 Spray向我的actor发送一条消息,要求提供数据,我提供了50个字节。一旦将此数据传递给操作系统,喷涂就会发送另一条消息,要求提供新数据。我提供了剩余的50个字节......然后完成了响应。
答案 0 :(得分:2)
是否可以在不使用[数据线]的HTTP块的情况下发送文件
是的,您需要启用无块流式传输。见http://spray.io/documentation/1.2.4/spray-routing/advanced-topics/response-streaming/
无论您是使用Stream marshaller还是以MessageChunk
自己提供响应,无块流式传输都能正常工作。请参阅以下示例。
没有将整个文件读入内存
是的,如果您将数据提供为Stream[Array[Byte]]
或Stream[ByteString]
,那么这应该有用。
[...]此后Spray会要求提供新数据[...]
实际上它几乎已经可以使用了:如果您手动提供块,您可以请求自定义Ack消息,当喷涂层能够处理下一部分时,该消息将被传递给您。有关如何从喷涂路线进行流式传输,请参阅this example。
我指的是我的内容长度为100字节
预先注意:在HTTP中,您不需要为响应指定内容长度,因为可以通过关闭连接来定界响应主体,如果启用无块流,则喷涂会执行此操作。但是,如果您不想关闭连接(因为您将丢失此持久连接),现在可以在Content-Length
消息中指定明确的ChunkedResponseStart
标头(请参阅#802)将阻止连接关闭。