13

我在 PHP 文档中看到的最接近的是 fread() 给定的长度,但这并没有指定从哪一行开始。还有其他建议吗?

4

7 回答 7

36

是的,你可以很容易地做到这一点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 行。

于 2010-05-11T08:34:50.493 回答
13

您将无法从第 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);
于 2009-02-05T05:37:46.637 回答
3

不幸的是,为了能够从第 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

于 2009-02-05T05:44:11.133 回答
3

这是可能的解决方案:)

<?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);
?>
于 2010-05-11T06:52:43.710 回答
3

好吧,您不能使用函数 fseek 来寻找适当的位置,因为它适用于给定的字节数。

我认为如果没有某种缓存或逐行遍历是不可能的。

于 2010-05-11T06:53:01.853 回答
0

如果您要查找行,则不能使用 fread,因为它依赖于字节偏移量,而不是换行符的数量。您实际上必须阅读文件才能找到换行符,因此使用不同的函数更合适。fgets将逐行读取文件。将其放入循环中并仅捕获您想要的行。

于 2009-02-05T05:40:57.240 回答
0

我害怕那个......我想这是B计划:S

对于每个 AJAX 请求,我将:

  1. 将我要返回给客户端的行数读入一个字符串。
  2. 将文件的其余部分复制到临时文件中。
  3. 返回字符串给客户端。

这很蹩脚,10,000+行文件可能会很慢,但我想这比一遍又一遍地阅读要好,至少每次请求都会使临时文件变短......不是吗?

于 2010-05-11T07:12:29.240 回答