ホームページ  >  記事  >  バックエンド開発  >  大きなファイルを素早く読み取るいくつかの PHP の例_PHP チュートリアル

大きなファイルを素早く読み取るいくつかの PHP の例_PHP チュートリアル

WBOY
WBOYオリジナル
2016-07-13 10:17:04844ブラウズ

PHP で大きなファイルを素早く読み取るいくつかの例

PHP でファイルを読み取るとき、最も速い方法は、file や file_get_contents などの関数を使用することです。わずか数行のコードで、非常に必要な関数を完成させることができます。美しく。ただし、操作するファイルが比較的大きなファイルの場合、これらの機能では不十分な場合があります。ここでは、大きなファイルを読み取るための一般的な操作方法について説明します。

需要

約 500 万行を含む 8 億のログ ファイルがあります。PHP を使用して最後の数行の内容を返します。

実施方法

1. ファイル機能を直接使用して操作します

ファイル関数はすべての内容を一度にメモリに読み取るため、また、不適切に作成されたプログラムがメモリを大量に消費し、システム メモリ不足を引き起こしてサーバーがクラッシュすることを防ぐために、PHP にはデフォルトで最大制限が設定されています。 php.ini のmemory_limit = 16M で設定されたメモリ 16M を使用します。この値が -1 に設定されている場合、メモリ使用量は制限されません。

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

コードは次のとおりです
ini_set('memory_limit', '-1');
$file = 'access.log';
$data = ファイル($file);
$line = $data[count($data) - 1];
エコー $line;
?>

コード全体の実行には 116.9613 (秒) かかります。

私のマシンには 2G のメモリがあり、F5 キーを押して実行すると、システムが灰色になり、ほぼ 20 分後にのみ回復します。このような大きなファイルをメモリに直接読み込むと重大な結果が生じることがわかります。いいえ、memory_limit をあまり高く調整することはできません。そうでない場合は、コンピューター室に電話してマシンをリセットするように依頼するしかありません。

2. Linux tail コマンドを直接呼び出して、最後の数行を表示します

Linux コマンドラインでは、tail -n 10 access.log を直接使用して、ログ ファイルの最後の数行を簡単に表示できます。PHP を直接使用して、tail コマンドを呼び出すことができます。

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

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

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

この方法は最も一般的な方法であり、ファイルの内容をすべて読み取る必要はなく、ポインターを介して直接操作するため、効率が非常に高くなります。 fseek を使用してファイルを操作する場合、さまざまな方法があり、効率が若干異なる場合があります。一般的に使用される方法は次の 2 つです。

方法1

最初に fseek を通じてファイルの最後の EOF を見つけ、次に最後の行の開始位置を見つけ、この行のデータを取得し、次に次の行の開始位置を見つけて、この行の位置を取得する、というように続きます。 $ 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);
$pos--;
}
$t = " ";
$data .= fgets($fp);
$line--;
}
fclose($fp);
$data をエコーする
?>

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

方法 2

引き続き fseek を使用してファイルの末尾から読み取りますが、今回は少しずつ読み取るのではなく、データを部分的に読み取るたびに、読み取ったデータを buf に配置します。データの最後の $num 行が改行文字 (\n) の数だけ読み取られたかどうかを確認します。

#実装コードは以下の通りです

コードは次のとおりです
$fp = fopen($file, "r");
$num = 10;
$チャンク = 4096;
$fs = sprintf("%u", ファイルサイズ($file));
$max = (intval($fs) == PHP_INT_MAX) : ファイルサイズ($file);
for ($len = 0; $len {
$seekSize = ($max - $len > $chunk) : $max - $len;
fseek($fp, ($len + $seekSize) * -1, SEEK_END);
$readData = fread($fp, $seekSize) . if (substr_count($readData, "\n") >= $num + 1)
{
preg_match("!(.*?\n){" . ($num) . "}$!", $readData, $match);
$data = $match[0];
休憩;
}
}
fclose($fp);
$data をエコー;
?>
コード全体の実行には 0.0009 秒かかります。

方法 3

コードは次のとおりです
関数 tail($fp, $n, $base = 5)
{
アサート($n > 0);
$pos = $n + 1;
$lines = array();
while (count($lines) {
試してみてください
{
fseek($fp, -$pos, SEEK_END);
}
catch (例外 $e)
{
fseek(0);
休憩
}
$pos *= $base;
その間 (!feof($fp))
{
array_unshift($lines, fgets($fp));
}
}

return array_slice($lines, 0, $n);

}

var_dump(tail(fopen("access.log", "r+"), 10));

?>

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

http://www.bkjia.com/PHPjc/895097.htmlwww.bkjia.comtru​​ehttp://www.bkjia.com/PHPjc/895097.html技術記事 PHP での大きなファイルの高速読み取りの例をいくつか示します。PHP でファイルを読み取るとき、最も速い方法は、file や file_get_contents などの関数をわずか数行で使用することです...
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。