How do I open a file from line X to line Y in PHP?

2019-01-11 05:26发布

问题:

The closest I've seen in the PHP docs, is to fread() a given length, but that doesnt specify which line to start from. Any other suggestions?

回答1:

You not going to be able to read starting from line X because lines can be of arbitrary length. So you will have to read from the start counting the number of lines read to get to line X. For example:

<?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);


回答2:

Yes, you can do that easily with SplFileObject::seek

$file = new SplFileObject('filename.txt');
$file->seek(1000);
for($i = 0; !$file->eof() && $i < 1000; $i++) {
    echo $file->current(); 
    $file->next();
}

This is a method from the SeekableIterator interface and not to be confused with fseek.

And because SplFileObject is iterable you can do it even easier with a LimitIterator:

$file = new SplFileObject('longFile.txt');
$fileIterator = new LimitIterator($file, 1000, 2000);
foreach($fileIterator as $line) {
    echo $line, PHP_EOL;
}

Again, this is zero-based, so it's line 1001 to 2001.



回答3:

Unfortunately, in order to be able to read from line x to line y, you'd need to be able to detect line breaks... and you'd have to scan through the whole file. However, assuming you're not asking about this for performance reasons, you can get lines x to y with the following:

$x = 10; //inclusive start line
$y = 20; //inclusive end line
$lines = file('myfile.txt');
$my_important_lines = array_slice($lines, $x, $y);

See: array_slice



回答4:

Here is the possible solution :)

<?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);
?>


回答5:

Well, you can't use function fseek to seek the appropriate position because it works with given number of bytes.

I think that it's not possible without some sort of cache or going through lines one after the other.



回答6:

If you're looking for lines then you can't use fread because that relies on a byte offset, not the number of line breaks. You actually have to read the file to find the line breaks, so a different function is more appropriate. fgets will read the file line-by-line. Throw that in a loop and capture only the lines you want.



回答7:

I was afraid of that... I guess it's plan B then :S

For each AJAX request I'm going to:

  1. Read into a string the number of lines I'm going to return to the client.
  2. Copy the rest of the file into a temp file.
  3. Return string to the client.

It's lame, and it will probably be pretty slow with 10,000+ lines files, but I guess it's better than reading the same over and over again, at least the temp file is getting shorter with every request... No?



标签: php fopen