ホームページ  >  記事  >  バックエンド開発  >  PHP_PHPチュートリアルで大容量ファイルの読み込み方法を詳しく解説

PHP_PHPチュートリアルで大容量ファイルの読み込み方法を詳しく解説

WBOY
WBOYオリジナル
2016-07-20 11:11:59763ブラウズ

この記事では、PHP で大容量ファイルを読み込む実装方法について詳しく説明します。詳しく知りたい学生は参考にしてください。

要件は次のとおりです: 約 500 万行の約 1G のログ ファイルがあり、php を使用して最後の数行の内容を返します。

実装方法:

1. ファイル関数を直接使用して操作します
注: ファイル関数はすべてのコンテンツを一度にメモリに読み取るため、PHP は、一部の不適切に作成されたプログラムがメモリを過剰に占有し、システムに障害が発生することを防ぎます。メモリが不足するとサーバーがクラッシュするため、デフォルトでは最大メモリ使用量が 16M に制限されます。この値が -1 に設定されている場合、メモリ使用量は制限されません。

以下は、file を使用してこのファイルの最後の行を抽出するコードです。
コード全体の実行には 116.9613 (s) かかります。

コードは次のとおりです コードをコピーします
ini_set('memory_limit', '-1');
$file = 'access.log';
$data = file($file);
$line = $data[count($data)-1];
echo $line;

私のマシンには 2G のメモリがあり、F5 キーを押して実行すると、システムが直接グレーになり、約 20 分後に回復します。メモリの問題は深刻なので、ここでは説明しません。最後の手段として、memory_limit を高く設定しすぎると、コンピューター室に電話してマシンをリセットする必要があります。

2. 表示するには、linux tail コマンドを直接呼び出します。最後の数行

Linux コマンド ラインでは、tail -n 10 access.log を使用して、ログ ファイルの最後の数行を簡単に表示できます。php を直接使用して、tail コマンドを呼び出し、php コードを実行できます。
コード全体の実行には 0.0034 (s) かかります

コードは次のとおりです コードをコピーします
file = 'access.log';
$file =scapeshellarg($file); //コマンドライン引数を安全にエスケープします
$line = `tail -n 1 $file`;
echo $line;

3. php の fseek を直接使用してファイル操作を実行します

この方法は最も一般的な方法です。ファイルの内容をすべてメモリに読み込む必要はありませんが、ポインタを介して直接操作します。そのため、fseek を使用してファイルを操作する場合は、さまざまな方法があり、その効率は若干異なる場合があります。よく使用される 2 つの方法
方法 1:
最初に fseek でファイルを検索し、最後の行の最後の EOF を見つけ、次に最後の行の開始位置を見つけ、この行のデータを取得し、次に次の行の開始位置を見つけます。 、次にこの行の位置を取得し、$num 行が見つかるまでこれを繰り返します。
実装コードは以下の通りです

コード全体の実行には0.0095(s)かかります

http://www.bkjia.com/PHPjc/444602.html
コードは以下の通りです コードをコピーします

function tail($fp,$n,$base=5 )
{
アサート( $n>0);
$pos = $n+1;
$lines = array();
while(count($lines) try{
fseek ($fp,-$pos .
array_unshift($lines,fgets ($fp));
return array_slice($lines,0,$n);

方法 2:

ファイルの末尾から読み取るには fseek を使用しますが、今回は 1 つずつではなく、データが読み取られるたびに 1 つずつ読み込まれます。 buf を取得し、改行文字の数 (n) を使用して、最後の $num 行のデータが読み込まれたかどうかを判断します。
実装コードは次のとおりです。
コード全体の実行には 0.0009(s) かかります。

コードは以下の通りです コードをコピー

$fp = fopen($file, "r");
$line = 10;
$pos = -2;
$t = " ";
$data = "";
while ( $line > 0) {
while ($t != "n") {
fseek($fp, $pos, SEEK_END);
$t = fgetc($fp);
$ pos --;
}
$t = " ";
$data .= fgets($fp);
$line --;
}
fclose ($fp);
echo $data

方法 3 :

コード全体の実行が完了しました 0.0003(s)かかります

コードは次のとおりです コードをコピー

$fp = fopen($file, "r");
$num = 10;
$chunk = 4096;
$fs = sprintf("%u", filesize($file));
$max = (intval($fs) == PHP_INT_MAX) : filesize($file);
for ($len = 0; $len $seekSize = ($max - $len > $chunk) : $max - $len;
fseek( $fp, ($len + $seekSize) * - 1, SEEK_END);
$readData = fread($fp, $seekSize) . $readData;

if (substr_count($readData, "n") >= $ num + 1) {
preg_match("!(. + echo $data;






www.bkjia.com

tru​​e

技術記事この記事では、PHP で大容量ファイルを読み込む実装方法について詳しく説明します。詳しく知りたい学生は参考にしてください。 要件は次のとおりです: 約 1G のログ ファイルがあり、約...
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。