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));,或者根据您的需要使用临时文件。