4
votes

I have a method save that takes an Iteratee it and saves some data to it. Inside the method, the data is available as an enumerator producing byte-array chunks.

def save[E](consumer: Iteratee[Array[Byte], E]): Future[E] = {
  val producer: Enumerator[Array[Byte]] = // ...
  Iteratee.flatten(producer(consumer)).run
}

Wanted: Call save in order to have it write the data to a FileOutputStream.

I tried the following but am not sure whether this is the way to go:

def writeToStream(s: OutputStream) =
  Iteratee.foreach((e: Array[Byte]) => s.write(e)).
    mapDone(r => { s.close(); r })
save(writeToStream(new FileOutputStream(myFile)))

Question: Is this the way it's supposed to be done? I fear that this will not always close the stream (case of exceptions).

I am using the Play Framework Iteratee library from Play Framework 2.1 (which uses Scala futures).

1

1 Answers

1
votes

The scaladocs for Iteratee say that it is in the responsibility of the "producer" not the iteratee to handle resources:

The Iteratee does not do any resource management (such as closing streams); the producer pushing stuff into the Iteratee has that responsibility.

You might be successful using the "onDoneEnumerating" method in Enumerator to clean up resources afterwards.

Scaladoc Iteratee