scala – 为什么我没有在SimpleResult体中组合枚举器?
发布时间:2020-12-16 18:11:38 所属栏目:安全 来源:网络整理
导读:我试图在 http://www.playframework.org/documentation/2.0/ScalaStream的“发送大量数据”下实现与第一个例子类似的东西. 我的不同之处在于我有多个文件要在响应中连接.它看起来像这样: def index = Action { val file1 = new java.io.File("/tmp/fileToSe
我试图在
http://www.playframework.org/documentation/2.0/ScalaStream的“发送大量数据”下实现与第一个例子类似的东西.
我的不同之处在于我有多个文件要在响应中连接.它看起来像这样: 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 ) } 发生的事情是只有第一个文件的内容在响应中. 稍微简单如下的一些工作正常: fileContent1 = Enumerator("blah" getBytes) fileContent2 = Enumerator("more blah" getBytes) SimpleResult( header = ResponseHeader(200),body = fileContent1 andThen fileContent2 ) 我错了什么? 解决方法
我通过阅读游戏代码获得了大部分内容,因此我可能会误解,但从我所看到的:Enumerator.fromFile函数(Iteratee.scala
[docs]
[src])创建一个枚举器,当应用于Iteratee [Byte,Byte]时]当从文件中读取时,将一个Input.EOF附加到Iteratee的输出.
根据Play!您链接到的docs示例应该在枚举器的末尾手动追加一个Input.EOF(Enumerator.eof的别名).我认为,将Input.EOF自动附加到文件字节数组的末尾是您只返回一个文件的原因. 播放控制台中等效的简单示例如下: scala> val fileContent1 = Enumerator("blah") andThen Enumerator.eof fileContent1: play.api.libs.iteratee.Enumerator[java.lang.String] = play.api.libs.iteratee.Enumerator$$anon$23@2256deba scala> val fileContent2 = Enumerator(" and more blah") andThen Enumerator.eof fileContent2: play.api.libs.iteratee.Enumerator[java.lang.String] = play.api.libs.iteratee.Enumerator$$anon$23@7ddeef8a scala> val it: Iteratee[String,String] = Iteratee.consume[String]() it: play.api.libs.iteratee.Iteratee[String,String] = play.api.libs.iteratee.Iteratee$$anon$18@6fc6ce97 scala> Iteratee.flatten((fileContent1 andThen fileContent2) |>> it).run.value.get res9: String = blah 修复,虽然我还没有尝试过这个,但是会更深入一些并直接使用Enumerator.fromCallback函数并传递一个自定义检索器函数,该函数不断返回Array [Byte],直到你想要的所有文件连接已被阅读.请参阅fromStream函数的实现,以查看默认值以及如何修改它. 如何执行此操作的示例(改编自Enumerator.fromStream): def fromFiles(files: List[java.io.File],chunkSize: Int = 1024 * 8): Enumerator[Array[Byte]] = { val inputs = files.map { new java.io.FileInputStream(_) } var inputsLeftToRead = inputs Enumerator.fromCallback(() => { def promiSEOfChunkReadFromFile(inputs: List[java.io.FileInputStream]): Promise[Option[Array[Byte]]] = { val buffer = new Array[Byte](chunkSize) (inputs.head.read(buffer),inputs.tail.headOption) match { case (-1,Some(_)) => { inputsLeftToRead = inputs.tail promiSEOfChunkReadFromFile(inputsLeftToRead) } case (-1,None) => Promise.pure(None) case (read,_) => { val input = new Array[Byte](read) System.arraycopy(buffer,input,read) Promise.pure(Some(input)) } } } promiSEOfChunkReadFromFile(inputs) },{() => inputs.foreach(_.close())}) } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |