このリンクで説明されているように、WS を使用してファイルをダウンロードするための単純な iteratee を作成しました。
次のスニペットを検討してください。
import java.nio.ByteBuffer
import java.nio.channels.FileChannel
import org.specs2.mutable.Specification
import org.specs2.time.NoTimeConversions
import play.api.libs.Files.TemporaryFile
import play.api.libs.iteratee.{Done, Input, Cont, Iteratee}
import play.api.libs.ws.WS
import scala.concurrent.Await
import scala.concurrent.duration._
import scala.concurrent.ExecutionContext.Implicits.global
class DummySpec extends Specification with NoTimeConversions {
def fileChannelIteratee(channel: FileChannel): Iteratee[Array[Byte], Unit] = Cont {
case Input.EOF =>
println("Input.EOF")
channel.close()
Done(Unit, Input.EOF)
case Input.El(bytes) =>
println("Input.El")
val buf = ByteBuffer.wrap(bytes)
channel.write(buf)
fileChannelIteratee(channel)
case Input.Empty =>
println("Input.Empty")
fileChannelIteratee(channel)
}
"fileChannelIteratee" should {
"work" in {
val file = TemporaryFile.apply("test").file
val channel = FileChannel.open(file.toPath)
val future = WS.url("http://www.example.com").get(_ => fileChannelIteratee(channel)).map(_.run)
Await.result(future, 10.seconds)
file.length !== 0
}
}
}
iteratee が Input.EOF を受け取っていないように見えるため、WS.get の後に .map(_.run) を呼び出しても、ここでは効果がないようです。チャンネルを閉じることができなくなります。これは私が得る出力です:
Input.El
[info] DummySpec
[info]
[info] fileChannelIteratee should
[info] x work (941 ms)
[error] '0' is equal to '0' (DummySpec.scala:37)
[info]
[info]
[info] Total for specification DummySpec
[info] Finished in 948 ms
[info] 1 example, 1 failure, 0 error
私は何を間違っていますか?
Play Framework 2.2.2 を使用しています。
前もって感謝します。