そのため、Play2.0 Enumeratee ページ&>
には、 orthrough
メソッドを使用して を に変更する例が示さEnumerator[String]
れていEnumerator[Int]
ます。
val toInt: Enumeratee[String,Int] = Enumeratee.map[String]{ s => s.toInt }
val ints: Enumerator[Int] = strings &> toInt
Enumeratee.grouped
個々の要素からチャンクの列挙子を作成する列挙型もあります。それはうまくいったようです。
しかし、私が見ているのは、通常の入力は( andArray[Byte]
によって返される) の形式になるということです。それを念頭に置いて、これらの入力を取得して、たとえば、各文字列が行である(で終わる)に変換したいと思います。通常、線と要素の境界は一致しません。チャンク配列をチャンク文字列に変換できる列挙子を作成するにはどうすればよいですか?Enumerator.fromFile
Enumerator.fromStream
Array[Byte]
Enumerator[String]
'\n'
Array[Byte]
目的は、これらの行が利用可能になるたびにブラウザにチャンクバックしArray[Byte]
、次の入力チャンクが来るまで完全な行の一部ではなかった残りのバイトを保持することです。
理想的には、 aniter: Iteratee[Array[Byte], T]
と anを指定すると、 T 要素が によって解析されたEnumerator[Array[Byte]]
an が返されるメソッドが欲しいです。Enumerator[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")