Así que la Play2.0 Enumeratee page muestra un ejemplo del uso de un método de la &>
o through
para cambiar una Enumerator[String]
en un Enumerator[Int]
:Cómo escribir un trozo enumeratee a un empadronador a lo largo de diferentes límites
val toInt: Enumeratee[String,Int] = Enumeratee.map[String]{ s => s.toInt }
val ints: Enumerator[Int] = strings &> toInt
Hay también un Enumeratee.grouped
enumeradoe para crear un enumerador de fragmentos de elementos individuales. Eso pareció funcionar bien.
Pero lo que veo es que la entrada habitual sería en forma de Array[Byte]
(que se devuelve por Enumerator.fromFile
y Enumerator.fromStream
). Con eso en mente, me gustaría tomar esas entradas Array[Byte]
y las convierte en Enumerator[String]
, por ejemplo, donde cada cadena es una línea (terminada por '\n'
). Los límites para las líneas y los elementos Array[Byte]
generalmente no coincidirán. ¿Cómo escribo un enumerador que puede convertir las matrices fragmentadas en cadenas fragmentadas?
El propósito es dividir esas líneas en el navegador cuando cada Array[Byte]
esté disponible y conservar los bytes sobrantes que no formaban parte de una línea completa hasta que aparezca el siguiente fragmento de entrada.
Idealmente me gustaría tener un método que da una iter: Iteratee[Array[Byte], T]
y un Enumerator[Array[Byte]]
me dará una vuelta Enumerator[T]
, donde mis elementos T fueron analizadas por iter
.
Información adicional: Tengo un poco de tiempo para limpiar mi código y aquí hay un ejemplo específico de lo que estoy tratando de hacer. Tengo las siguientes iteratees que detectan la siguiente línea:
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
Y lo que me gustaría hacer es algo así:
Ok.stream(Enumerator.fromFile(filename) &> chunkBy(line)).as("text/plain")
fresca. Sentí que 'agrupado' debería haber hecho lo que yo quería. – huynhjl