Iteratees make it possible to consume streams of data in a non-blocking way. Conversely, enumerators produce data streams in a non-blocking way. They are useful when you need to send large results, or if your result is built from an intermittent data source. An Enumerator[A]
object defines a stream of values of type A
.
The simplest way to create an enumerator is to use one of the methods of the Enumerator
object. For instance, you can easily convert a java.io.InputStream
class or a java.io.File
class to an Enumerator[Array[Byte]]
object as follows:
import play.api.libs.iteratee.Enumerator Enumerator.fromStream(inputStream) Enumerator.fromFile(file)
To send a stream of data as a response body, it is better to explicitly set the Content-Length
response header so that the connection can be kept alive to serve further requests. Alternatively, you can use the chunked transfer encoding as follows:
Ok.chunked(Enumerator.fromFile(new File("foo.txt")))
To use the chunked transfer encoding in Java, you have to pass a Chunks
value to your result:
StringChunks chunks = (out) -> { out.write("foo"); out.write("bar"); out.close(); } return ok(chunks);
Note, however, that in the case of files, it is even better to use the sendFile
method:
Ok.sendFile(new File("foo.txt"))
The sendFile
method reads the file size using the filesystem and sets the Content-Length
header accordingly so that the web browser can display a nice progress bar while downloading the response content. The Content-Type
header is also set according to the file extension. Finally, it also sets the Content-Disposition
header to the attachment so that browsers download the file instead of displaying it.
In Java, simply pass File
as a parameter of your result:
return ok(new File("foo.txt"));
3.21.246.223