删除文件行,不需要使用file_get_content将整个文件加载到缓冲区中,也不需要使用fwrite逐行重写整个文件省略要删除的行,只需删除一行并操作一行,假设文件有1,000,000行。
我尝试将要删除的行转换为空格,然后用trim()删除它们:
$line_to_delete = 2;
$file = fopen('./test_key.txt', 'r+');
if ($file) {
for ($i = 1; $i < $line_to_delete; $i++) {
fgets($file); // Moves the pointer to the beginning of the line to delete.
}
};
$start_line_to_delete = ftell($file); // Saves the position of the beginning of the line to be deleted.
fgets($file); // Read the line and leave the pointer at the end.
$start_next_line = ftell($file); // Saves the position of the start of the next line.
fseek($file , $start_line_to_delete ); // Moves the pointer to the beginning of the line.
$line_length_to_delete = $start_next_line - $start_line_to_delete; // Calculate the length of the line.
for ($i = 0; $i < $line_length_to_delete - 1; $i++) { // -1 prevents deleting the line break of the line.
fwrite($file, ' '); // Pad the line to delete with white space.
};
fseek($file, $start_line_to_delete); // Returns to the position after the line to be deleted.
fwrite($file, trim(fgets($file))); // I try to remove whitespace with trim().
做完之后
fwrite($file, trim(fgets($file)));
您必须截断文件。否则,您将获得文件最后
N
字节的副本,其中 N
是您删除的行的大小。
使用
ftruncate($file, ftell($file));
您不需要先在该行上写空格。只需读取文件的其余部分,查找该行开始的位置,然后用文件的其余部分覆盖它。
$start_line_to_delete = ftell($file);
fgets($file);
$rest_of_file = fgets($file);
fseek($file, $start_line_to_delete);
fwrite($file, $rest_of_file);
unset($rest_of_file);
ftruncate($file, ftell($file);
就内存使用而言,这与您的
fwrite($file, trim(fgets($file)));
没有什么不同——它们都使用 fgets($file)
将文件的其余部分读入内存。唯一的区别是我的将其暂时放入变量中;我用 unset
清理它。