我有一个脚本可以逐行解析大文件。当它遇到无法处理的错误时,它会停下来,通知我们解析的最后一行。
这真的是寻找文件中特定行的最佳/唯一方法吗?(fseek()
在我的情况下不可用。)
<?php
for ($i = 0; $i < 100000; $i++)
fgets($fp); // just discard this
我使用它没有问题,它足够快 - 只是感觉有点脏。根据我对底层代码的了解,我认为没有更好的方法可以做到这一点。
查找文件中特定行的一种简单方法是使用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 代码除外)。
如果您只有行号可以继续,则没有其他方法可以找到该行。文件不是基于行的(甚至不是基于字符的),因此无法简单地跳转到文件中的特定行。
可能还有其他读取文件行的方法可能会稍微快一些,例如将文件的较大块读取到缓冲区中并从中读取行,但您只能希望它快几个百分点。任何在文件中查找特定行的方法仍然必须读取该行之前的所有数据。
我知道发帖已经晚了,但它可以帮助一些人,我有一天做了一个像 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,也一样
rewind($handle);
for ($i=0; $i < $desired_line; $i++) {
fgetcsv($handle, 1000, ",");
}
当我需要在脚本中多次倒退到特定行时,这对我有用。
我不确定这是否会消耗内存或速度,但它可以解决问题。
如果我理解正确,您想在发现错误后的某个时间点查找特定行。如果是这种情况,您可能会在某处存储或打印坏行的行号,具体取决于“通知”的含义。
除非您真的是说您不能使用fseek()
*,否则您可以做的是也存储/打印文件中坏行开始的位置。然后就可以了fseek()
。
* 在这种情况下,fseekbyline()
如果它存在,它会如何使用?