So ist die Play2.0 Enumeratee page zeigt ein Beispiel der Verwendung eines der &>
oder through
Methode zu ändern ein Enumerator[String]
in ein Enumerator[Int]
ein enumeratee zu Chunk einen Enumerator schreiben:Wie entlang verschiedener Grenzen
val toInt: Enumeratee[String,Int] = Enumeratee.map[String]{ s => s.toInt }
val ints: Enumerator[Int] = strings &> toInt
Es ist auch Ein Enumeratee.grouped
Enumeratee zum Erstellen eines Enumerators von Chunks aus einzelnen Elementen. Das schien gut zu funktionieren.
Aber was ich sehe, ist, dass die übliche Eingabe in Form von Array[Byte]
sein würde (die von Enumerator.fromFile
und Enumerator.fromStream
zurückgegeben wird). In diesem Sinne würde ich gerne diese Array[Byte]
Eingänge nehmen und sie zu einem Enumerator[String]
machen, zum Beispiel wenn jeder String eine Zeile ist (terminiert durch einen '\n'
). Die Grenzen für die Linien und die Array[Byte]
Elemente stimmen normalerweise nicht überein. Wie schreibe ich einen Enumerator, der die Chunked-Arrays in Chunked-Strings konvertieren kann?
Der Zweck besteht darin, diese Zeilen zurück zum Browser zu chunken, da jedes Array[Byte]
verfügbar wird, und die übrig gebliebenen Bytes zu behalten, die nicht Teil einer vollständigen Zeile waren, bis der nächste Eingabeklotz kommt.
Im Idealfall würde ich gerne ein Verfahren haben, die eine iter: Iteratee[Array[Byte], T]
gegeben und ein Enumerator[Array[Byte]]
geben Sie mir eine Enumerator[T]
zurück, wo meine T Elemente von iter
analysiert wurden.
Zusätzliche Informationen: Ich hatte ein wenig Zeit, um meinen Code aufzuräumen und hier ist ein konkretes Beispiel für das, was ich versuche zu tun. Ich habe folgende iteratees, die die nächste Zeile erkennen:
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
Und was ich möchte ist so etwas zu tun:
Ok.stream(Enumerator.fromFile(filename) &> chunkBy(line)).as("text/plain")
Kühle beheben. Es fühlte sich an, als ob "gruppiert" hätte tun sollen, was ich wollte. – huynhjl