2

リクエスト時に動的に作成される比較的大きなファイルを提供する Web サービスを開発しています。私の場合、これは多数のファイルを含む ZIP アーカイブ ファイルですが、他の種類の動的に作成されたファイルでも同じ問題が発生すると思います。

問題は、ディスク上に ZIP ファイルを作成することを避けたいということです。むしろ、それを HTTP 応答に直接ストリーミングするだけです。私が考えた 1 つの方法は、チャンク ストリーミングを使用することです。これは、ストリーミング アクターが一度にチャンクを送信し、次のチャンクを送信する前にレスポンダーからの確認を「待機」することを意味します。( https://github.com/spray/spray/blob/release/1.1/examples/spray-routing/on-spray-can/src/main/scala/spray/examples/DemoService.scalaの例をsendStreamingResponse参照)

残念ながら、私が見つけることができるすべての例は、ストリームが事前に定義されている場合にそれを行う方法を示していますが、データのストリームが他の将来に準備されている場合にこれにアプローチする最良の方法はよくわかりません.

私の場合、Futureファイルをフェッチし、java.util.zip.ZipOutputStream. しかし、Spray でのストリーミングのしくみは逆です。ストリーミング アクターは、データの準備ができたときにデータをプルする必要があるためです。すべてのデータをストリームにプッシュすることはできません。

これはおなじみの使用例ですか?それに取り組む最善の方法は何ですか?

4

1 に答える 1

0

を生成する場合、Spray のビルトイン マーシャラーを使用できると思いますSteam[Byte]。私はそれを試していませんが、このようなものはうまくいくはずです(過去に動的な画像のサイズ変更と大きなファイルの提供で同様のことをしました)。

val pipeIn = new PipedInputStream()
val pipeOut = new PipedOutputStream(pipeIn)
val out = new ByteArrayOutputStream()
val st = new ZipOutputStream(out)
Future{
  writeToZip(st)
  out.writeTo(pipeOut)
}
val streamResponse: Stream[Byte] = Stream.continually(pipeIn.read).takeWhile(_ != -1).map(_.toByte)
complete(streamResponse)

スプレーのストリーム マーシャラーは、チャンクされた応答を自動的に生成します。

于 2015-11-12T14:16:20.817 に答える