ホームページ  >  記事  >  バックエンド開発  >  1G ファイルサイズを読み取る PHP 実装_PHP チュートリアル

1G ファイルサイズを読み取る PHP 実装_PHP チュートリアル

WBOY
WBOYオリジナル
2016-07-21 14:59:01785ブラウズ

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

1. file 関数を直接使用して操作しないと、file_get_content() が確実にメモリ オーバーフローを報告します
注: file 関数はすべてのコンテンツを一度にメモリに読み込むため、PHP は、不適切に作成されたプログラムの実行を防ぐために、メモリを消費しすぎるとシステム メモリが不足し、サーバーがクラッシュするため、デフォルトでは最大メモリ使用量は 16M に制限されます。この値が -1 に設定されている場合、これは php.ini のmemory_limit = 16M によって設定されます。メモリ使用量に制限はありません。

以下は、file を使用してこのファイルの最後の行を抽出するコードです。

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

ini_set('memory_limit','-1');
$file = 'access.log ';
$data = file($file);
$line = $data[count($data)-1];2. Linux tail コマンドを直接呼び出して、最後の数行を表示します。

Linux コマンドラインでは、tail -n 10 access.log を直接使用して、ログ ファイルの最後の数行を簡単に表示できます。次のように、php を直接使用して tail コマンドを呼び出し、php コードを実行できます。
コードをコピーします コードは次のとおりです:

file = 'access.log';
$file =escapeshellarg($file) // コマンドラインパラメータを安全にエスケープします
$line = `tail - n 1 $file`;
echo $line;3. php を直接使用する fseek は、ファイル操作を実行する最も一般的な方法であり、ファイルのすべての内容をメモリに読み取る必要はありませんが、ポインターを介して直接操作します。 fseek を使用してファイルを操作する場合の効率は非常に効率的です。 操作にはさまざまな方法があり、効率は若干異なる場合があります。一般的に使用される 2 つの方法を以下に示します。

方法 1:

最初に fseek を通じてファイルの最後の EOF を見つけ、次に最後の行の開始位置を見つけ、この行のデータを取得し、次に次の行の開始位置を見つけて、 $num 行が見つかるまで、この行の位置などを調べます。
コードをコピーします

コードは次のとおりです: function tail($fp,$n,$base=5){
assert($n>0);
$pos = $n+ 1;
$ Lines = array();
while(count($lines)< =$n){
try{
fseek($fp,-$pos,SEEK_END);
fseek(0 ); }
return array_slice($lines, 0,$n);
}
var_dump(tail(fopen("access.log","r+"),10));




方法 2:


引き続き fseek を使用するファイルの末尾から読み込みを開始しますが、今回はビットごとに読み取るのではなく、データを部分的に読み取るたびに、読み取ったデータが buf に配置され、その数が続きます。改行文字 (n) を使用して、最後の $num 行のデータが読み取られたかどうかを確認します。

実装コードは次のとおりです


コードをコピーします
コードは次のとおりです:
$fp = fopen($file, "r");
$line = 10;$pos = -2 ;

$t = " " ;
$data = "";

while ($line > 0) { while ($t != "n") { fseek($fp, $pos, SEEK_END); $t = fgetc($fp } データメソッド 3:



コードをコピーします

コードは次のとおりです:

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

if (substr_count($readData, "n") >= $num + 1) {
preg_match("!(.*?n){".($num)."}$!", $ readData、$match)
readData, $match);



http://www.bkjia.com/PHPjc/328160.html

www.bkjia.com
tru​​e

http://www.bkjia.com/PHPjc/328160.html

要件は次のとおりです。 約 500 万行の約 1G のログ ファイルがあり、PHP を使用して最後の数行の内容を返します。 1. file 関数を直接使用して操作するか、file_get_content() が確実にレポートします...
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。