Vì vậy, các Play2.0 Enumeratee page thấy một ví dụ của việc sử dụng một phương pháp &>
hoặc through
để thay đổi một Enumerator[String]
thành một Enumerator[Int]
:Làm thế nào để viết một enumeratee đến đoạn một Enumerator dọc theo ranh giới khác nhau
val toInt: Enumeratee[String,Int] = Enumeratee.map[String]{ s => s.toInt }
val ints: Enumerator[Int] = strings &> toInt
Ngoài ra còn có một Enumeratee.grouped
liệt kê để tạo ra một điều tra các khối từ các phần tử riêng lẻ. Điều đó dường như làm việc tốt.
Nhưng những gì tôi thấy là đầu vào thông thường sẽ ở dạng Array[Byte]
(được trả về bởi Enumerator.fromFile
và Enumerator.fromStream
). Với ý nghĩ đó, tôi muốn lấy những đầu vào Array[Byte]
và biến chúng thành một Enumerator[String]
, ví dụ trong đó mỗi chuỗi là một dòng (được kết thúc bởi một '\n'
). Ranh giới cho các đường và các phần tử Array[Byte]
thường không khớp. Làm thế nào để tôi viết một điều tra viên có thể chuyển đổi các mảng chunked thành chuỗi chunked?
Mục đích là để chunk những dòng này trở lại trình duyệt vì mỗi Array[Byte]
trở nên khả dụng và giữ các byte còn thừa không phải là một phần của dòng hoàn chỉnh cho đến khi đoạn nhập tiếp theo xuất hiện.
Lý tưởng nhất là tôi muốn có phương thức được cấp iter: Iteratee[Array[Byte], T]
và Enumerator[Array[Byte]]
sẽ trả lại cho tôi Enumerator[T]
, trong đó các phần tử T của tôi được phân tích cú pháp theo iter
.
Thông tin bổ sung: Tôi đã có một chút thời gian để dọn sạch mã của tôi và đây là một ví dụ cụ thể về những gì tôi đang cố gắng làm. Tôi có iteratees sau đó phát hiện các dòng tiếp theo:
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
Và những gì tôi muốn làm là một cái gì đó như thế:
Ok.stream(Enumerator.fromFile(filename) &> chunkBy(line)).as("text/plain")
mát. Có vẻ như 'nhóm lại' nên đã làm những gì tôi muốn. – huynhjl