Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/apache-flex/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在PHP中打开从X行到Y行的文件?_Php_Fopen - Fatal编程技术网

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

如何在PHP中打开从X行到Y行的文件?,php,fopen,Php,Fopen,我在PHP文档中看到的最接近于fread()的一个给定长度,但它没有指定从哪一行开始。还有其他建议吗?您不能从X行开始阅读,因为行可以是任意长度的。因此,您必须从开始计算读取的行数开始读取,才能到达第X行。例如: <?php $f = fopen('sample.txt', 'r'); $lineNo = 0; $startLine = 3; $endLine = 6; while ($line = fgets($f)) { $lineNo++; if ($lineNo &

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

您不能从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);

如果要查找行,则不能使用fread,因为这取决于字节偏移量,而不是换行数。实际上,您必须读取文件才能找到换行符,因此使用不同的函数更合适。将逐行读取文件。把它放在一个循环中,只捕获你想要的行。

不幸的是,为了能够从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);
请参阅:

<?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来查找适当的位置,因为它使用给定的字节数


我认为如果没有某种缓存或一行接一行地检查,这是不可能的。

我很害怕。。。我想是B计划吧:s

对于每个AJAX请求,我将:

  • 将要返回到客户机的行数读入字符串
  • 将文件的剩余部分复制到临时文件中
  • 将字符串返回到客户端

  • 这是蹩脚的,它可能会非常慢,10000多行的文件,但我想这比一遍又一遍地读取相同的文件要好,至少临时文件会随着每个请求而变短。。。否?

    是的,您可以用


    同样,这是从零开始的,所以是第1001到2001行。

    或者你可以使用file()和array_slice(),就像我的回答:)是的,除了读取整个文件。这段代码只读取所需的最小值。即使文件如此庞大(比如我当前需要处理的文件是25MB),它也可以工作吗?@lock,是的,应该可以。我举的例子在记忆中只有一行。只要行数不太多,就可以将行存储到数组中。话虽如此,与我必须处理的一些日志文件相比,25Mb并不是很大。如果您在长时间运行的脚本和较低版本的PHP中遇到内存问题,最好尽量避免使用对象,这就是为什么我更喜欢@grom的答案。您应该注意,数组以0开头,行号通常以0开头1.所以应该有一个$x-1、$y-1或者记住$x=10实际上是$x=11。但是它读取x之前的所有行。问题是这部分是否可以跳过,不是吗?请参阅
    $startine
    $endLine
    变量,它将只读取这些行。问题不是只处理给定的行(>=startLine&&这是一个很好的解决方案,但仍然很耗时。文件越深入,花费的时间就越长……我打算处理10000+行的文件。@thedp:让我们看看是否有更好的解决方案:)行缓存呢?将每行的字节位置存储在某个地方,然后使用fseek()去了解它们。@christian studer:你说的是索引文件?如果文件是静态的,并且大部分时间不会更改,这可能是一个有趣的解决方案。不幸的是,我要读的文件是源代码文件,仍在开发中,所以索引是不可能的。是的,索引它并缓存索引。(文件上的时间戳可能会指示缓存的索引是否仍然有效)。PHP在执行这些任务时速度惊人,如果在同一文件再次更改之前有多个请求,则可能足够快以完成此任务。+1 SPL非常好,可以使用更多广告(和文档)请记住,SPL实现的实现方式与第一个建议的解决方案相同。它将从第一个字节开始读取文件,每次读取一行,并将文件指针保留在所需的行上。无法回避该问题。
    $file = new SplFileObject('filename.txt');
    $file->seek(1000);
    for($i = 0; !$file->eof() && $i < 1000; $i++) {
        echo $file->current(); 
        $file->next();
    }
    
    $file = new SplFileObject('longFile.txt');
    $fileIterator = new LimitIterator($file, 1000, 2000);
    foreach($fileIterator as $line) {
        echo $line, PHP_EOL;
    }