18

我有一个脚本可以逐行解析大文件。当它遇到无法处理的错误时,它会停下来,通知我们解析的最后一行。

这真的是寻找文件中特定行的最佳/唯一方法吗?(fseek()在我的情况下不可用。)

<?php

for ($i = 0; $i < 100000; $i++)
    fgets($fp); // just discard this

我使用它没有问题,它足够快 - 只是感觉有点脏。根据我对底层代码的了解,我认为没有更好的方法可以做到这一点。

4

5 回答 5

37

查找文件中特定行的一种简单方法是使用SplFileObject类,它支持查找行号 ( seek()) 或字节偏移量 ( fseek())。

$file = new SplFileObject('myfile.txt');
$file->seek(9999);     // Seek to line no. 10,000
echo $file->current(); // Print contents of that line

在后台,seek()只执行您的 PHP 代码所做的事情(C 代码除外)。

于 2011-09-30T21:32:17.723 回答
4

如果您只有行号可以继续,则没有其他方法可以找到该行。文件不是基于行的(甚至不是基于字符的),因此无法简单地跳转到文件中的特定行。

可能还有其他读取文件行的​​方法可能会稍微快一些,例如将文件的较大块读取到缓冲区中并从中读取行,但您只能希望它快几个百分点。任何在文件中查找特定行的方法仍然必须读取该行之前的所有数据。

于 2010-08-27T22:44:45.350 回答
4

我知道发帖已经晚了,但它可以帮助一些人,我有一天做了一个像 fseekbyline 这样的功能......

function GoToLine($handle,$line)
{
  fseek($handle,0);  // seek to 0
  $i = 0;
  $bufcarac = 0;                    

  for($i = 1;$i<$line;$i++)
  {
    $ligne = fgets($handle);
    $bufcarac += strlen($ligne);  // in the end bufcarac will contains all caracters until the line
  }  

  fseek($handle,$bufcarac);
}

没有错误系统,如果您想转到 <1 或 203 行但文件为空...您将一无所获。

如果您想退出eot,也一样

于 2011-09-30T21:22:52.783 回答
1
rewind($handle);

for ($i=0; $i < $desired_line; $i++) {
    fgetcsv($handle, 1000, ",");
}

当我需要在脚本中多次倒退到特定行时,这对我有用。

我不确定这是否会消耗内存或速度,但它可以解决问题。

于 2014-07-22T14:07:14.183 回答
0

如果我理解正确,您想在发现错误后的某个时间点查找特定行。如果是这种情况,您可能会在某处存储或打印坏行的行号,具体取决于“通知”的含义。

除非您真的是说您不能使用fseek()*,否则您可以做的是也存储/打印文件中坏行开始的位置。然后就可以了fseek()

* 在这种情况下,fseekbyline()如果它存在,它会如何使用?

于 2010-08-28T01:21:04.513 回答