Come lo script Scala che legge file di log 5G da un'unità di rete deve essere modificato al fine di leggere le linee ultimi x (come 'coda' in Unix)?
Domanda
Come lo script Scala che legge file di log 5G da un'unità di rete deve essere modificato al fine di leggere le linee x ultimi (come 'coda' in 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)
}
}
Soluzione
Io sto usando una coda mutabile in questo:
::#!@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)
}
}
Se si utilizza una coda di immutabile, userei un reduceLeft, ma non vedo nessun punto nel usando una coda immutabile per questo.
Altri suggerimenti
Se la lettura del file è costoso, come mi aspetto che sia attraverso la rete, io cerco di fine del file e leggere pezzi progressivamente più grandi (più conoscenza del dominio del formato di file di registro potrebbe dare una strategia migliore qui ) dalla fine fino a trovare il numero di linee che stai cercando.
Avrete ovviamente tenere un buffer di righe x, che si aggiorna ad ogni iterazione:
var buf: List[String] = Nil
for (line <- ...) {
buf = (buf ::: List(line)) match {
case x :: xs if (xs.length == n) => xs
}
}