PHP fwrite() 复制并替换通过 fgets() 获得的行
PHP fwrite() duplicates and replaced rows obtained through fgets()
我正在尝试编写一个小的 php 函数,它每 10 行读取一次,检测是否有分号并将其替换为提交语句 ; => into ; commit;
。
我正在使用 fgets,因为该文件可能非常大,如 1GB,而我不想将它保存到另一个新文件中,这会占用额外的空间。
我的职能是
$targetFile = fopen($file,'r+');
// if can open
if ($targetFile){
$count ='';
// loop every line
while (($lines = fgets($targetFile)) !== false){
$count++;
// for line of no.10
if( $count == '10' ){
//if matches a semi-colon
if( preg_match('/;/',$lines) == true ){
// replace semi-colon with commit statement
$insertLine = preg_replace('/;/','; commit;', $lines);
echo file_get_contents('./1.sql'); // to debug
fwrite($targetFile, $insertLine); // <= problem arises
echo file_get_contents('./1.sql'); // to debug
//reset counter
$count = '0';
}else{
//lower the count to check next line
--$count;
}
}
}
}else{
system("echo file $targetFile cannot be opened\n");
}
fclose($targetFile);
目标文件执行前
LINE1;
LINE2;
LINE3;
LINE4;
LINE5;
LINE6;
LINE7;
LINE8;
LINE9;
LINE10;
LINE11;
LINE12;
LINE13;
执行后:
LINE1;
LINE2;
LINE3;
LINE4;
LINE5;
LINE6;
LINE7;
LINE8;
LINE9;
LINE10;
LINE10; commit;
LINE13;
问题是为什么 fwrite() 会替换第 11 行并删除第 12 行
问题是,当您使用 while (($lines = fgets($targetFile)) !== false)
遍历文件时,文件指针向前移动。所以当你到达第 10 行时,你的文件指针已经指向下一行,第 11 行,所以你覆盖第 11 行。
所以这就是我要做的:
$filename = "input.txt";
$in = fopen($filename,'r+');
if($in)
{
$count = 0;
$last = 0;
// loop every line
while (($lines = fgets($in)) !== false)
{
$count++;
if( $count % 10 == 0 && preg_match('/;/',$lines) )
{
$content = file_get_contents($filename, FALSE, null, ftell($in));
$insertLine = preg_replace('/;/',"; commit;", $lines);
// go back to the end of the last line
fseek($in, $last, SEEK_SET);
fwrite($in, $insertLine);
// insert the content from the next line to the end, otherwise it will modified. You see this if you remove this line
fwrite($in, $content);
}
else
{
//Save the position where ends the last line
$last = ftell($in);
}
}
}
else
{
echo "Input file cannot be opened\n";
}
fclose($in);
您可以找到一种更有效的方法来获取文件的内容$content = file_get_contents($filename, FALSE, null, ftell($in));
,或者根据您的需要使用临时文件。
我正在尝试编写一个小的 php 函数,它每 10 行读取一次,检测是否有分号并将其替换为提交语句 ; => into ; commit;
。
我正在使用 fgets,因为该文件可能非常大,如 1GB,而我不想将它保存到另一个新文件中,这会占用额外的空间。
我的职能是
$targetFile = fopen($file,'r+');
// if can open
if ($targetFile){
$count ='';
// loop every line
while (($lines = fgets($targetFile)) !== false){
$count++;
// for line of no.10
if( $count == '10' ){
//if matches a semi-colon
if( preg_match('/;/',$lines) == true ){
// replace semi-colon with commit statement
$insertLine = preg_replace('/;/','; commit;', $lines);
echo file_get_contents('./1.sql'); // to debug
fwrite($targetFile, $insertLine); // <= problem arises
echo file_get_contents('./1.sql'); // to debug
//reset counter
$count = '0';
}else{
//lower the count to check next line
--$count;
}
}
}
}else{
system("echo file $targetFile cannot be opened\n");
}
fclose($targetFile);
目标文件执行前
LINE1;
LINE2;
LINE3;
LINE4;
LINE5;
LINE6;
LINE7;
LINE8;
LINE9;
LINE10;
LINE11;
LINE12;
LINE13;
执行后:
LINE1;
LINE2;
LINE3;
LINE4;
LINE5;
LINE6;
LINE7;
LINE8;
LINE9;
LINE10;
LINE10; commit;
LINE13;
问题是为什么 fwrite() 会替换第 11 行并删除第 12 行
问题是,当您使用 while (($lines = fgets($targetFile)) !== false)
遍历文件时,文件指针向前移动。所以当你到达第 10 行时,你的文件指针已经指向下一行,第 11 行,所以你覆盖第 11 行。
所以这就是我要做的:
$filename = "input.txt";
$in = fopen($filename,'r+');
if($in)
{
$count = 0;
$last = 0;
// loop every line
while (($lines = fgets($in)) !== false)
{
$count++;
if( $count % 10 == 0 && preg_match('/;/',$lines) )
{
$content = file_get_contents($filename, FALSE, null, ftell($in));
$insertLine = preg_replace('/;/',"; commit;", $lines);
// go back to the end of the last line
fseek($in, $last, SEEK_SET);
fwrite($in, $insertLine);
// insert the content from the next line to the end, otherwise it will modified. You see this if you remove this line
fwrite($in, $content);
}
else
{
//Save the position where ends the last line
$last = ftell($in);
}
}
}
else
{
echo "Input file cannot be opened\n";
}
fclose($in);
您可以找到一种更有效的方法来获取文件的内容$content = file_get_contents($filename, FALSE, null, ftell($in));
,或者根据您的需要使用临时文件。