【发布时间】:2012-05-07 23:07:07
【问题描述】:
因此,Play2.0 Enumeratee page 显示了使用&> 或through 方法将Enumerator[String] 更改为Enumerator[Int] 的示例:
val toInt: Enumeratee[String,Int] = Enumeratee.map[String]{ s => s.toInt }
val ints: Enumerator[Int] = strings &> toInt
还有一个Enumeratee.grouped enumeratee 用于从单个元素创建块的枚举器。这似乎工作正常。
但我看到的是通常的输入形式为Array[Byte](由Enumerator.fromFile 和Enumerator.fromStream 返回)。考虑到这一点,我想将这些Array[Byte] 输入转换为Enumerator[String],例如每个字符串都是一行(以'\n' 结尾)。线条和Array[Byte] 元素的边界通常不匹配。如何编写可以将分块数组转换为分块字符串的枚举器?
目的是在每个Array[Byte] 可用时将这些行分块回浏览器,并保留不属于完整行的剩余字节,直到下一个输入块出现。
理想情况下,我希望有一个方法,给出iter: Iteratee[Array[Byte], T] 和Enumerator[Array[Byte]] 将返回Enumerator[T],其中我的T 元素由iter 解析。
附加信息:我有一些时间来清理我的代码,这是我正在尝试做的一个具体示例。我有以下检测下一行的迭代:
import play.api.libs.iteratee._
type AB = Array[Byte]
def takeWhile(pred: Byte => Boolean): Iteratee[AB, AB] = {
def step(e: Input[AB], acc: AB): Iteratee[AB, AB] = e match {
case Input.EOF => Done(acc, Input.EOF)
case Input.Empty => Cont(step(_, acc))
case Input.El(arr) =>
val (taking, rest) = arr.span(pred)
if (rest.length > 0) Done(acc ++ taking, Input.El(rest))
else Cont(step(_, acc ++ taking))
}
Cont(step(_, Array()))
}
val line = for {
bytes <- takeWhile(b => !(b == '\n' || b == '\r'))
_ <- takeWhile(b => b == '\n' || b == '\r')
} yield bytes
而我想做的是这样的:
Ok.stream(Enumerator.fromFile(filename) &> chunkBy(line)).as("text/plain")
【问题讨论】:
标签: scala playframework enumerator playframework-2.0 iterate