如何在 PHP 中打开从第 X 行到第 Y 行的文件?

发布于 2024-07-12 11:17:24 字数 64 浏览 5 评论 0原文

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

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

依 靠 2024-07-19 11:17:24

是的,您可以使用 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 行。

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.

许仙没带伞 2024-07-19 11:17:24

您将无法从第 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);

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);
-黛色若梦 2024-07-19 11:17:24

不幸的是,为了能够从第 x 行读取到第 y 行,您需要能够检测换行符......并且您必须扫描整个文件。 但是,假设您出于性能原因询问此问题,则可以使用以下内容获取 xy 行:

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

请参阅:array_slice

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

羁〃客ぐ 2024-07-19 11:17:24

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

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

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.

半窗疏影 2024-07-19 11:17:24

这里是可能的解决方案:)

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

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);
?>
枕头说它不想醒 2024-07-19 11:17:24

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

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.

嘿咻 2024-07-19 11:17:24

我很害怕...我想这是 B 计划然后:S

对于每个 AJAX 请求,我将: 将

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

它很蹩脚,对于 10,000 多行文件来说可能会很慢,但我想这比一遍又一遍地读取相同的文件要好,至少临时文件随着每个请求而变得越来越短......不是吗?

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?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文