gpt4 book ai didi

scala - 为什么我无法在 SimpleResult 主体中组合枚举器?

转载 作者:行者123 更新时间:2023-12-05 00:33:04 27 4
gpt4 key购买 nike

我试图在 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
)

我怎么了?

最佳答案

我通过阅读 Play 代码获得了大部分内容,所以我可能误解了,但是从我所看到的:Enumerator.fromFile function(Iteratee.scala [docs] [src]) 创建一个枚举器,当应用于 Iteratee[Byte, Byte] 时附加一个 Input.EOF当它完成从文件中读取时,到 Iteratee 的输出。

根据剧!您链接到的 docs 示例应该在枚举器的末尾手动附加 Input.EOF(Enumerator.eof 的别名)。我认为,将 Input.EOF 自动附加到文件字节数组的末尾是您只返回一个文件的原因。

Play 控制台中等效的更简单示例是:

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] s 直到您要连接的所有文件都已被读取。引用 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, 0, input, 0, read)
Promise.pure(Some(input))
}
}
}
promiseOfChunkReadFromFile(inputs)
}, {() => inputs.foreach(_.close())})
}

关于scala - 为什么我无法在 SimpleResult 主体中组合枚举器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12603414/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com