Каков наилучший способ перезаписи определенной строки в файле? Я в основном хочу искать файл для строки «@parsethis» и перезаписывать остальную часть этой строки чем-то другим.
Если файл не слишком большой, лучшим способом, вероятно, будет чтение файла в массив строк с файлом () , поиск по массиву строк для вашей строки и редактирование этой строки, а затем implode () массив обратно вместе и fwrite () обратно в файл.
Если файл действительно большой (файлы журналов или что-то вроде этого), и вы готовы пожертвовать скоростью для потребления памяти, вы можете открыть два файла и по существу сделать трюк Джереми Рутен, предлагаемый с использованием файлов вместо системной памяти.
$source='in.txt'; $target='out.txt'; // copy operation $sh=fopen($source, 'r'); $th=fopen($target, 'w'); while (!feof($sh)) { $line=fgets($sh); if (strpos($line, '@parsethis')!==false) { $line='new line to be inserted' . PHP_EOL; } fwrite($th, $line); } fclose($sh); fclose($th); // delete old source file unlink($source); // rename target file to source file rename($target, $source);
Основная проблема заключается в том, что новая строка может быть не такой же длины, как у старой строки. Если вам нужно изменить длину строки, нет пути перезаписи, по крайней мере, всего файла после измененной строки. Самый простой способ – создать новый, измененный файл, а затем переместить его поверх оригинала. Таким образом, для читателей всегда доступен полный файл. Используйте блокировку, чтобы убедиться, что один скрипт одновременно модифицирует файл, и поскольку вы собираетесь заменить файл, выполните блокировку в другом файле. Проверьте flock()
.
Если вы уверены, что новая строка будет такой же длины, как и в старой строке, вы можете открыть файл в режиме чтения / записи (используйте r+
в качестве второго аргумента для fopen()
) и вызовите ftell()
чтобы сохранить позицию строка запускается каждый раз, прежде чем вы fgets()
чтобы прочитать строку. Когда вы найдете строку, которую хотите переписать, вы можете использовать fseek()
чтобы вернуться к началу строки и fwrite()
новые данные. Один из способов заставить линию всегда иметь одинаковую длину – это пространство, которое выкладывает на максимально возможную длину.
или если ваш файл не слишком большой:
$sample = file_get_contents('sample'); $parsed =preg_replace('#@parsethis.*#', 'REPLACE TO END OF LINE', $sample);
Вам придется выбирать разделители '#', которые не присутствуют в файле.
Я, скорее всего, сделаю то, что предложил Джереми, но просто для альтернативного способа сделать это здесь – другое решение. Это не было протестировано или использовано, и оно предназначено для систем * nix.
$cmd = "grep '@parsethis' " . $filename; $output = system($cmd, $result); $lines = explode("\n", $result); // Read the entire file as a string // Do a str_repalce for each item in $lines with ""