PHP ドキュメントで見た中で最も近いのは、指定された長さを fread() することですが、どの行から開始するかを指定していません。他の提案はありますか?
7 に答える
はい、あなたはそれを簡単に行うことができますSplFileObject::seek
$file = new SplFileObject('filename.txt');
$file->seek(1000);
for($i = 0; !$file->eof() && $i < 1000; $i++) {
echo $file->current();
$file->next();
}
これはSeekableIteratorインターフェイスのメソッドであり、 と混同しないでくださいfseek
。
SplFileObject は反復可能であるため、次のようにするとさらに簡単に実行できますLimitIterator
。
$file = new SplFileObject('longFile.txt');
$fileIterator = new LimitIterator($file, 1000, 2000);
foreach($fileIterator as $line) {
echo $line, PHP_EOL;
}
繰り返しますが、これはゼロベースなので、1001 行目から 2001 行目です。
行は任意の長さになる可能性があるため、行 X から読み取ることはできません。したがって、行 X に到達するために読み取った行数を最初から読み取る必要があります。たとえば、次のようになります。
<?php
$f = fopen('sample.txt', 'r');
$lineNo = 0;
$startLine = 3;
$endLine = 6;
while ($line = fgets($f)) {
$lineNo++;
if ($lineNo >= $startLine) {
echo $line;
}
if ($lineNo == $endLine) {
break;
}
}
fclose($f);
<?php
$f = fopen('sample.txt', 'r');
$lineNo = 0;
$startLine = 3;
$endLine = 6;
while ($line = fgets($f)) {
$lineNo++;
if ($lineNo >= $startLine) {
echo $line;
}
if ($lineNo == $endLine) {
break;
}
}
fclose($f);
?>
関数 fseek を使用して適切な位置をシークすることはできません。これは、指定されたバイト数で機能するためです。
なんらかのキャッシュや、次々と行をたどらないと無理だと思います。
残念ながら、行 x から行 y までを読み取るには、改行を検出できる必要があり、ファイル全体をスキャンする必要があります。ただし、パフォーマンス上の理由からこれについて質問していないと仮定すると、次の行x
を取得できます。y
$x = 10; //inclusive start line
$y = 20; //inclusive end line
$lines = file('myfile.txt');
$my_important_lines = array_slice($lines, $x, $y);
参照: array_slice
私はそれを恐れていました...それはプランBだと思います:S
AJAX リクエストごとに、次のことを行います。
- クライアントに返す行数を文字列に読み込みます。
- ファイルの残りの部分を一時ファイルにコピーします。
- 文字列をクライアントに返します。
それは不十分で、おそらく10,000行以上のファイルではかなり遅くなりますが、同じものを何度も読むよりはましだと思います.少なくとも一時ファイルはリクエストごとに短くなります...いいえ?
行を探している場合は、 fread を使用できません。これは、改行の数ではなく、バイト オフセットに依存するためです。実際にはファイルを読み取って改行を見つける必要があるため、別の関数の方が適しています。fgetsはファイルを 1 行ずつ読み取ります。それをループに入れて、必要な行だけをキャプチャします。