Я пытаюсь удалить строку из середины большого файла. (> 20 МБ). Я знаю позицию в файле начала строки, которую нужно удалить.Удаление строки из середины большого файла php
Вот что у меня есть.
/**
* Removes a line at a position from the file
* @param [int] $position The position at the start of the line to be removed
*/
public function removeLineAt($position)
{
$fp = fopen($this->filepath, "rw+");
fseek($fp, $position);
$nextLinePosition = $this->getNextLine($position, $fp);
$lengthRemoved = $position - $nextLinePosition;
$fpTemp = fopen('php://temp', "rw+");
// Copy the bottom half (starting at line below the line to be removed)
stream_copy_to_stream($fp, $fpTemp, -1, $nextLinePosition);
// Seek to the start of the line to be removed
fseek($fp, $position);
rewind($fpTemp);
// Copy the bottom half over the line to be removed
stream_copy_to_stream($fpTemp, $fp);
fclose($fpTemp);
fclose($fp);
}
Однако, хотя код выше действительно удаляет строку из файла; поскольку временный файл короче исходного файла. Хвост исходного файла все еще существует и удваивается.
Для примера: Исходный файл был
- б
- с
- д
- е
Файл после удаления строки может выглядеть
- б
- d
- е
- е
Я думал о том-то обрезки конец основного файла на величину $ lengthRemoved однако я не могу подумайте о том, как легко это сделать.
Любые предложения?
- Примечание: файл имеет> 200 000 линий, иногда> 300 000. Я чувствую, что загрузка всего файла в массив (память) будет довольно неэффективной. Именно поэтому я попытался выше подход, но столкнулся, что один вопрос
Для других, которые ищут ответ здесь конечная функция, которую я придумал благодаря вашей помощи! Измените его в соответствии с вашими потребностями.
/**
* Removes a line at a position from the file
* @param [int] $position The position at the start of the line to be removed
*/
public function removeLineAt($position)
{
$fp = fopen($this->filepath, "rw+");
fseek($fp, $position);
$nextLinePosition = $this->getNextLine($position, $fp);
$lengthRemoved = $position - $nextLinePosition;
$fpTemp = fopen('php://temp', "rw+");
// Copy the bottom half (starting at line below the line to be removed)
stream_copy_to_stream($fp, $fpTemp, -1, $nextLinePosition);
// Remove the difference
$newFileSize = ($this->totalBytesInFile($fp) + $lengthRemoved);
ftruncate($fp, $newFileSize);
// Seek to the start of the line to be removed
fseek($fp, $position);
rewind($fpTemp);
// Copy the bottom half over the line to be removed
stream_copy_to_stream($fpTemp, $fp);
fclose($fpTemp);
fclose($fp);
}
Возможный дубликат [Как удалить некоторую строку из текстового файла с помощью PHP?] (Http://stackoverflow.com/questions/14250773/how-to-remove-some-line-from-text-file-using- php) – cmorrissey
Файл имеет> 200 000 строк и может содержать> 400 000. Я чувствую, что загрузка всего файла в массив (память) будет довольно неэффективной. Вот почему я попробовал вышеуказанный подход, но столкнулся с этой проблемой. – user4775085