Im trying to achieve something similar to the first example under “Sending large amounts of data” at http://www.playframework.org/documentation/2.0/ScalaStream.
What I am doing differently is that I have more than one file that I want to concatenate in the response. It looks like this:
def index = Action {
val file1 = new java.io.File("/tmp/fileToServe1.pdf")
val fileContent1: Enumerator[Array[Byte]] = Enumerator.fromFile(file1)
val file2 = new java.io.File("/tmp/fileToServe2.pdf")
val fileContent2: Enumerator[Array[Byte]] = Enumerator.fromFile(file2)
SimpleResult(
header = ResponseHeader(200),
body = fileContent1 andThen fileContent2
)
}
What happens is that only the contents of the first file is in the response.
Something slightly simpler like below works fine though:
fileContent1 = Enumerator("blah" getBytes)
fileContent2 = Enumerator("more blah" getBytes)
SimpleResult(
header = ResponseHeader(200),
body = fileContent1 andThen fileContent2
)
What am I getting wrong?
I’ve got most of this from reading through the play code so I might have misunderstood, but from what I can see: the
Enumerator.fromFilefunction(Iteratee.scala [docs][src]) creates an enumerator which when applied to anIteratee[Byte, Byte]appends anInput.EOFto the output of the Iteratee when it’s done reading from the file.According to the Play! docs example that you linked to you’re supposed to manually append an Input.EOF (alias of Enumerator.eof) at the end of the enumerator. I would think that, having an Input.EOF automatically appended to the end of the file’s byte array is the reason that you’re getting only one file returned.
The equivalent simpler example in the play console would be:
The fix, although I haven’t tried this yet would be to go a few levels deeper and use the
Enumerator.fromCallbackfunction directly and pass it a custom retriever function that keeps returningArray[Byte]s until all the files that you want to concatenate have been read. Refer to the implementation of thefromStreamfunction to see what the default is and how to modify it.An example of how to do this (adapted from
Enumerator.fromStream):