Итак, страница Play2.0 Enumeratee показывает пример использования &>
или through
для преобразования Enumerator[String]
в Enumerator[Int]
:
val toInt: Enumeratee[String,Int] = Enumeratee.map[String]{ s => s.toInt }
val ints: Enumerator[Int] = strings &> toInt
. Существует также метод Enumeratee.grouped
для создания перечислителя фрагментов из отдельных элементов. Это, казалось, работало нормально.
Но я вижу, что обычный ввод будет в форме 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")