2009-11-03 9 views
1

Как скрипт Scala, который считывает файл журнала 5G с сетевого диска, должен быть изменен, чтобы читать последние строки x (например, «хвост» в Unix)?Как скрипт Scala, который считывает файл журнала 5G с сетевого диска, должен быть изменен, чтобы читать последние строки x (например, «хвост» в 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) 
} 
} 

ответ

2

Я использую изменяемый очереди в этой:

::#[email protected] 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, но я не вижу смысла использовать для этого неизменяемую очередь.

+0

Чтение всего файла 5G по сети и сброс всех, кроме последних 5 строк, кажется идеальным. – copumpkin

+0

Это не так. Вам нужно будет прочитать блоки байтов с конца, пока не получите необходимое количество строк, чтобы сделать это правильно, используя пару стеков для строк - один для текущего блока, один для общего. Это требует прохождения через библиотеку ввода-вывода Java, которая так ужасна, что я не буду касаться, не заплатив за нее. :-) –

+1

Также невозможно прочитать из файла назад, если вы не знаете, что кодировка является фиксированной длиной –

0

Вы, очевидно, придется держать буфер х линий, которые вы обновляете на каждой итерации:

var buf: List[String] = Nil 

for (line <- ...) { 
    buf = (buf ::: List(line)) match { 
    case x :: xs if (xs.length == n) => xs 
    } 
} 
+1

Разве это ужасно уродливый способ сделать то же самое, что сделал Даниэль с изменчивой очередью? (Это тоже неэффективно, так как buf должен быть скопирован в линейном времени на каждой итерации цикла.) –

+1

Я упростил совпадение (я все делал для ясности). Я думаю, вам нужно прочитать постоянную структуру данных Scala, поскольку копирование не происходит, используя 'List'. Я думаю, что это очень * элегантно * лично! –

+1

Oxbow, buf _is_ копируется в линейном времени. Аргумент слева от ':::' всегда копируется. Это '::', который ничего не копирует. –

2

Если чтение файла стоит дорого, так как я ожидаю, что это по сети, я бы поискал до конца файла и читал постепенно более крупные фрагменты (больше знаний о домене в формате файла журнала может дать вам лучшую стратегию здесь) с конца, пока не найдете количество строк, которые вы ищете.

 Смежные вопросы

  • Нет связанных вопросов^_^