2013-07-24 4 views
0

Я читаю из файлов журнала, которые могут быть любыми из небольшого файла журнала до 8-10 мб журналов. Типичный размер, вероятно, составит 1 мб. Теперь самое главное, что ключевое слово im ищет, как правило, около конца документа, вероятно, в 95% случаев. Затем я извлекаю 1000 символов после ключевого слова.Чтение файла журнала в массив обратный, это лучший метод при поиске ключевого слова в нижней части?

Если я использую этот подход:

$lines = explode("\n",$body); 
$reversed = array_reverse($lines); 
foreach($reversed AS $line) { 
// Search for my keyword 
} 

Будет ли это быть более ЭФФЕКТИВНАЯ, чем при использовании:

$pos = stripos($body,$keyword); 
$snippet_pre = substr($body, $pos, 1000); 

Что я не уверен, что на это с stripos делает это просто начать поиск по документу 1 персонаж за один раз, так что теоретически, если после ключевого слова 10 000 символов, тогда мне не придется читать их в памяти, тогда как первый вариант должен будет читать все в памяти, даже если ему, вероятно, нужны только последние 100 строк, я могу изменить он считывает 100 строк в память, затем поиск других 101-200 строк, если первые 100 не были успешными или запрос настолько светлый, что это действительно не имеет значения.

У меня 2-й вопрос, и это предполагает, что reverse_array является наилучшим подходом, как бы я извлечь следующие 1000 символов после того, как я нашел ключевое слово, вот мой горестный попытка

$body = $this_is_the_log_content; 

$lines = explode("\n",$body); 
$reversed = array_reverse($lines); 
foreach($reversed AS $line) { 

$pos = stripos($line,$keyword); 
$snippet_pre = substr($line, $pos, 1000); 

} 

Why i don't think that will work is because each $line might only be a few hundred characters so would the better solution be to explode it every say 2,000 lines and also keep the previous $line as a backup variable so something like this. 

$body = $this_is_the_log_content; 

$lines = str_split($body, 2000); 
$reversed = array_reverse($lines); 
$previous_line = $line; 
foreach($reversed AS $line) { 

$pos = stripos($line,$keyword); 
    if ($pos) { 
    $line = $previous_line . ' ' . $line; 
    $pos1 = stripos($line,$keyword); 
    $snippet_pre = substr($line, $pos, 1000); 
    } 

} 

Im вероятно массово над - Сочетание этого?

+0

Рассматривали ли вы использование инструментов командной строки, таких как 'grep', для достижения этого? Кажется, очень дорого загружать все эти файлы в память. –

+0

не нужно менять массив ... просто выполните цикл for с декрементирующим индексом – Orangepill

+0

Можете ли вы, ребята, развернуть бит, у меня есть только опыт PHP, так что grep что-то я могу реализовать с помощью своего php? Я в основном извлекаю всю информацию из журнала и вставляю ее в MYsql для последующего использования. Я не понимаю, что вы имеете в виду, когда вы видите декрементный индекс, можете ли вы указать пример? – user1547410

ответ

0

Я бы очень хотел использовать такой инструмент, как grep. Вы можете вызвать этот инструмент командной строки из PHP и использовать его для поиска файла для искомого слова и делать такие вещи, как дать вам смещение байта соответствующей строки, дать вам подходящую строку плюс конечные строки контекста и т. Д.

Вот ссылка на руководство grep. http://unixhelp.ed.ac.uk/CGI/man-cgi?grep

Play с помощью команды немного в командной строке, чтобы получить его так, как вы хотите его, а затем вызвать его из PHP с помощью exec(), passthru(), или аналогичные в зависимости от того, как вам нужно, чтобы захватить/отображать содержимое.

В качестве альтернативы вы можете просто указать fopen() файл с указателем в конце и переместить указатель файла в файл, используя fseek(), ища строку при перемещении по пути. После того, как вы найдете иглу, вы можете прочитать файл с этого смещения, пока не дойдете до конца файла или количества записей в журнале.

Любой из них может быть предпочтительнее читать весь файл журнала в памяти и затем пытаться работать с ним.

Другая вещь, которую следует учитывать, имеет значение 1000 символов. Обычно файлы журнала имеют строки, которые различаются по длине. Мне кажется, что вы должны больше беспокоиться о том, чтобы получить следующие строки X из файла журнала, а не следующие символы Y. Что, если строка имеет 2000 символов, вы говорите, что хотите получить только половину? Это может не иметь смысла.