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()
можно было бы использовать, если бы оно существовало?