Fseek() по строке, а не байтам?

У меня есть script, который анализирует большие файлы по строкам. Когда он сталкивается с ошибкой, которую он не может обработать, он останавливается, уведомляя нас о последней анализируемой строке.

Это действительно лучший/единственный способ поиска определенной строки в файле? (fseek() не применимо в моем случае.)

<?php

for ($i = 0; $i < 100000; $i++)
    fgets($fp); // just discard this

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

Ответы

Ответ 1

Простым способом поиска определенной строки в файле является использование класса SplFileObject, который поддерживает поиск номера строки (seek()) или смещение байта (fseek()).

$file = new SplFileObject('myfile.txt');
$file->seek(9999);     // Seek to line no. 10,000
echo $file->current(); // Print contents of that line

В фоновом режиме seek() просто выполняет то, что сделал ваш PHP-код (кроме кода C).

Ответ 2

Если у вас есть только номер строки для продолжения, другого метода поиска линии нет. Файлы не основаны на линиях (или даже на основе символов), поэтому нет возможности просто перейти к определенной строке в файле.

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

Ответ 3

Я знаю, что поздно публиковать, но это может помочь некоторым ppl В один прекрасный день я сделал функцию fseekbyline...

function GoToLine($handle,$line)
{
  fseek($handle,0);  // seek to 0
  $i = 0;
  $bufcarac = 0;                    

  for($i = 1;$i<$line;$i++)
  {
    $ligne = fgets($handle);
    $bufcarac += strlen($ligne);  // in the end bufcarac will contains all caracters until the line
  }  

  fseek($handle,$bufcarac);
}

нет системы ошибок, если вы хотите перейти на строку < 1 или 203, но файл пуст... вы не получите ничего хорошего.

то же самое, если вы хотите выйти из eot

Ответ 4

rewind($handle);
while($i=0; $i<$desired_line; i++)
    fgetcsv($handle, 1000, ",")

Это работает для меня, в то время как мне нужно перематывать на определенную строку несколько раз в моем script.

Я не уверен, что это поглощает память или скорость, но это делает трюк.

Ответ 5

Если я правильно понял, вы хотите найти конкретную строку в какой-то момент после того, как нашли ошибку. Если это так, вы, вероятно, храните или печатаете номер строки плохой строки где-нибудь, в зависимости от того, что вы подразумеваете под "уведомлением".

Если вы действительно не имеете в виду, что вы не можете использовать fseek() *, то вы можете также сохранить/распечатать позицию в файле, где начинается неправильная строка. Тогда вы можете fseek().

* Как в таком случае fseekbyline() можно было бы использовать, если бы оно существовало?