Как следует модифицировать скрипт Scala, который считывает файл журнала 5G с сетевого диска, чтобы читать последние x строк (например, 'tail' в Unix)?
Вопрос
Как следует модифицировать скрипт Scala, который считывает файл журнала 5G с сетевого диска, чтобы читать последние x строк (например, 'tail' в Unix)?
::#!
@echo off
call scala %0 %*
goto :eof
::!#
import scala.io.Source
if (args.length > 0) {
for (line <-Source.fromFile(args(0)).getLines)
if(line.contains("percent")){
print(line)
}
}
Решение
В этом я использую изменяемую очередь:
::#!@echo off
call scala %0 %*
goto :eof
::!#
import scala.io.Source
val lastN = 5 // I guess you'll be getting them from args, but...
val queue = new scala.collection.mutable.Queue[String]
if (args.length > 0) {
Source.fromFile(args(0)).getLines foreach { line =>
queue.enqueue(line)
if (queue.size > lastN) queue.dequeue
}
for (line <- queue)
if (line.contains("percent")){
print(line)
}
}
Если бы использовалась неизменяемая очередь, я бы использовал reduceLeft , но я не вижу смысла использовать неизменяемую очередь для этого.
Другие советы
Если чтение файла обходится дорого, поскольку я предполагаю, что это делается по сети, я бы обратился к концу файла и читал постепенно увеличивающиеся фрагменты (более глубокое знание формата файла журнала может дать вам лучшую стратегию здесь) с конца, пока вы не найдете нужное количество строк.
Очевидно, вам придется сохранить буфер из x строк, который вы обновляете на каждой итерации:
var buf: List[String] = Nil
for (line <- ...) {
buf = (buf ::: List(line)) match {
case x :: xs if (xs.length == n) => xs
}
}