ホームページ >バックエンド開発 >PHPの問題 >PHPで大きなファイルの末尾にあるn行を読み取る効率的な方法

PHPで大きなファイルの末尾にあるn行を読み取る効率的な方法

藏色散人
藏色散人オリジナル
2021-07-23 09:23:332445ブラウズ

PHP で大きなファイルの末尾にある n 行を読み取る方法: 最初にポインタを末尾に移動し、2 つの位置に戻ります。次に、fgetc を介して文字を読み取り、関連する判断を行います。最後に fgets を直接使用して、文字を変換する 行全体を取り出すだけです。

PHPで大きなファイルの末尾にあるn行を読み取る効率的な方法

この記事の動作環境: Windows7 システム、PHP7.1 バージョン、DELL G3 コンピューター

php では n 行が読み込まれます。大きなファイルの終わり 効率的な方法

は以下の全員に共有され、全員の参考にもなります。

数メガバイト以内の小さなファイルの場合は、file() 関数を使用してファイルを配列に 1 行ずつ読み取り、array_pop を使用して最後の行を取得できます。

しかし、非常に大きなテキスト ファイルの場合、マシンのメモリが十分に大きくないか、PHP 自体にmemory_limit 制限があるため、この方法は適用できません。制限がない場合でも、効率は非常に低くなります。

他に方法はないのでしょうか?もちろんありますが、既成の機能はないので自分でやる必要があります。

ここではファイル ポインタを使用する必要があります。C を勉強したことがある人はポインタが何であるかを知っていると思います。簡単に言うと、PHP では、ファイルは fopen を通じて開かれます。この時点では、ファイルはまだ開かれていません。このとき、指すポインタはファイルの先頭であり、ポインタの位置は0です fgetsやfgetcでファイルの内容を読み込むと、読み込むにつれてポインタが進みます。

while(!feof($fp)){
$data.=fgets($fp,4096);
}

の原理 つまり、fgets は、改行文字が見つかるまで、指定された長さの文字列を現在のポインター位置から逆方向に読み取ります。

では、下から N 行目へのポインタの位置を制御することは可能でしょうか?残念ながらできませんが、 fseek() 関数を使用して、ポインタを末尾や N 位置まで直接移動できます。

まずポインタを最後まで移動し、2 つ前の位置に戻り、fgetc で文字を読み取り、その文字が改行文字である "\n" であるかどうかを判断します。前の行の最後の改行文字まで戻って、fgets を使用して行全体を取り出すだけです。ここでは 2 つの while ループが使用されており、外側のループは取得する行数を制御し、内側のループは fseek アクションを制御します。

関数は次のとおりです:

/**
 * 取文件最后$n行
 * @param string $filename 文件路径
 * @param int $n 最后几行
 * @return mixed false表示有错误,成功则返回字符串
 */
function FileLastLines($filename,$n){
  if(!$fp=fopen($filename,'r')){
    echo "打开文件失败,请检查文件路径是否正确,路径和文件名不要包含中文";
    return false;
  }
  $pos=-2;
  $eof="";
  $str="";
  while($n>0){
    while($eof!="\n"){
      if(!fseek($fp,$pos,SEEK_END)){
        $eof=fgetc($fp);
        $pos--;
      }else{
        break;
      }
    }
    $str.=fgets($fp);
    $eof="";
    $n--;
  }
  return $str;
}
echo nl2br(FileLastLines('sss.txt',4));

推奨学習: "PHP ビデオ チュートリアル "

以上がPHPで大きなファイルの末尾にあるn行を読み取る効率的な方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。