PHP での大きなファイルの読み取りと通常のファイルの読み取りにはいくつかの違いがあります。ファイルが数百 MB または数百 GB の場合、通常の PHP 読み取りファイルは非常に遅くなるか、スタックする可能性があります。大きなファイルの読み取りに関するヒントを紹介します。
通常、ファイルを読み取るには fopen または file_get_contents を使用します。前者はループで読み取ることができ、後者は一度に読み取ることができますが、どちらもファイルの内容を一度に読み込みます。ロードするファイルが数百Mなど特に大きく、Gサイズに達するとパフォーマンスが低下する場合、PHPで大きなファイルを処理するための関数またはクラスはありますか? 答えは「はい」です。
PHP は本当に「オブジェクト指向」になってきており、元の基本的な SPL メソッドのいくつかが次々とクラスを実装し始めています。
PHP 5.1.0 以降、SPL ライブラリには 2 つの標準ファイル操作クラス、SplFileObject と SplFileInfo が追加されました。 SplFileInfo は PHP 5.1.2 以降で実装されています。
文字通りの意味から、SplFileObject は SplFileInfo よりも強力であることがわかります。
はい、SplFileInfo は、ファイル サイズ、ファイル アクセス時間、ファイル変更時間、サフィックス名、その他の値など、ファイルの一部の属性情報を取得するためにのみ使用され、SplFileObject は SplFileInfo のこれらの機能を継承します。
コードは次のとおりです |
コードをコピー |
/**ファイルの内容を X 行目から Y 行目まで返します (php5、php4 をサポート)
* @param string $filename ファイル名
* @param int $startLine 開始行番号
* @param int $endLine 終了行番号
* @戻り文字列
*/
function getFileLines($filename, $startLine = 1, $endLine=50, $method='rb') {
$content = array();
$count = $endLine - $startLine ;
// PHPのバージョンを確認する(SplFileObjectを使用しているため、PHP>=5.1.0)
If(version_compare(PHP_VERSION, '5.1.0', '>=')){
$fp = new SplFileObject($filename, $method);
$fp->seek($startLine-1);//N 行目に移動すると、seek メソッドのパラメーターは 0 からカウントされます
for($i = 0; $i
$content[]=$fp->current();// current() は現在の行の内容を取得します
$fp->next();//次の行
}
}else{//PHP
$fp = fopen($filename, $method);
If(!$fp) は「エラー: ファイルを読み取れません」を返します;
for ($i=1;$i
fgets($fp);
}
for($i;$i
$content[]=fgets($fp);// ファイル行の内容を読み取ります
}
fclose($fp);
}
return array_filter($content); //array_filter フィルター: false,null,''
}
|
追伸: !$fp->eof() または !feof($fp) には「最後まで読む」という判定が追加されていません。また、この判定は多くの動作をテストする必要があります。時間が経てばわかるでしょうが、ここに追加する必要はまったくありません。
上記の関数から、特にファイル行数が非常に多く、次のコンテンツをフェッチする必要がある場合、SplFileObject を使用する方が以下の fgets よりもはるかに高速であることがわかります。 fgets には 2 つのループが必要で、$endLine 回ループする必要があります。
この方法には多大な労力がかかり、最も効率的な方法を見つけるために多くの中国語の書き方をテストしました。改善すべき点があると思われる方がいらっしゃいましたら、ぜひお知らせください。
行 35270 ~ 35280 の内容を使用して返します:
コードは次のとおりです |
コードをコピー |
エコー ' ';<br>
var_dump(getFileLines('test.php',35270,35280));<br>
エコー ' ';
|
別の例を見てください
コードは次のとおりです
| コードをコピー
|
関数 readBigFile($filename, $count = 20, $tag = "rn") {
$content = "";//最終コンテンツ
$current = "";//現在読んでいるコンテンツのストレージ
$step= 1;//毎回ステップする文字数
$tagLen = strlen($tag);
$start = 0;//開始位置
$i = 0;//カウンター
$handle = fopen($filename,'r+');//ファイルを読み取り/書き込みモードで開き、ポインターはファイルの開始位置を指します
while($i < $count && !feof($handle)) {
fseek($handle, $start, SEEK_SET);//ポインターはファイルの先頭に設定されます
$current = fread($handle,$step);//ファイルを読み取る
$content .= $current;// 結合された文字列
$start += $step;//ステップサイズに従って前に進みます
//区切り文字の長さに基づいて文字列の最後の数文字を切り詰めます
$substrTag = substr($content, -$tagLen);
if ($substrTag == $tag) { //改行か他の区切り文字かを判断します
$i++;
$content .= " ";
}
}
//ファイルを閉じる
fclose($ハンドル);
//結果を返す
$content を返します。
}
$filename = "csdn.sql";//読み取るファイル
$tag = "n";//行区切り文字 ここでは二重引用符を使用する必要があることに注意してください
$count = 100;//読み取られた行数
$data = readBigFile($filename,$count,$tag);
$data をエコー;
注: PHP の fseek と fread を組み合わせると、関数によって渡される変数 $tag の値は、システムによって異なりますが、ファイル内のデータの特定の部分を任意に読み取ることができます。違いは、Windows は「rn」を使用し、linux/unix は「n」を使用し、Mac OS は「r」を使用します。
|
http://www.bkjia.com/PHPjc/632771.html
www.bkjia.comtrue
http://www.bkjia.com/PHPjc/632771.html
技術記事 PHP で大きなファイルを読み取る場合と、通常のファイルを読み取る場合とでは、いくつかの違いがあります。ファイルが数百 MB または GB の場合、通常の PHP ではファイルの読み取りが遅くなったり、スタックしたりする可能性があります。