I am trying to remove a line from the middle of a large file. (> 20 MB). I know the position in the file of the beginning of the line that needs to be deleted.
Here is what I have now.
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+");
stream_copy_to_stream($fp, $fpTemp, -1, $nextLinePosition);
fseek($fp, $position);
rewind($fpTemp);
stream_copy_to_stream($fpTemp, $fp);
fclose($fpTemp);
fclose($fp);
}
However, although the code above does remove the line from the file; because the temporary file is shorter than the original file. The tail of the source file still exists and doubles.
For example: The source file was
The file after deleting the line may look like
I thought of somehow trimming the end of the main file using the $ lengthRemoved number, but I can't think of an easy way to do this.
Any suggestions?
- . > 200 000 , a > 300 000. , () . , .
, , , ! .
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+");
stream_copy_to_stream($fp, $fpTemp, -1, $nextLinePosition);
$newFileSize = ($this->totalBytesInFile($fp) + $lengthRemoved);
ftruncate($fp, $newFileSize);
fseek($fp, $position);
rewind($fpTemp);
stream_copy_to_stream($fpTemp, $fp);
fclose($fpTemp);
fclose($fp);
}