我正在尝试从大文件的中间删除一行。 (> 20MB)。我知道要删除的行开头的文件中的位置。
这是我现在拥有的。
/**
* 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);
}
但是,虽然上面的代码确实从文件中删除了该行;因为临时文件比原始文件短。原始文件的尾端仍然存在并加倍。
例如: 原始文件是
删除行后的文件可能看起来像
我已经想过以某种方式通过$ lengthRemoved量来修剪主文件的结尾但是我想不出一个简单的方法来做到这一点。
有什么建议吗?
对于那些正在寻找答案的人来说,这是我提出的最终功能,感谢您的帮助!修改它以满足您的需求。
/**
* 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);
}
答案 0 :(得分:1)
我认为你非常接近解决方案。
我会坚持你从文件末尾删除$lengthRemoved
的想法,并建议在ftruncate($handle, $size);
之前使用fclose()
,其中size是要截断的大小( size = originalFilesize - lengthRemoved)。
答案 1 :(得分:1)
由于您的文件非常大,如果您的php安装允许您使用该功能,您可能希望通过sed
使用exec
命令。
exec("sed '3d' fileName.txt");
3
表示所需的行号。