代码之家  ›  专栏  ›  技术社区  ›  jasonbar

fseek()按行,而不是按字节?

  •  18
  • jasonbar  · 技术社区  · 14 年前

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

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

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

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

    5 回复  |  直到 10 年前
        1
  •  35
  •   salathe    13 年前

    查找文件中特定行的一种简单方法是使用 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
    

    在背景中, 搜索() 只做你的PHP代码所做的(除了在C代码中)。

        2
  •  4
  •   Guffa    14 年前

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

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

        3
  •  2
  •   Olive    13 年前

    我知道张贴晚了,但它可以帮助一些PPL 有一天我做了一个类似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也一样

        4
  •  1
  •   Alan Helton    10 年前
    rewind($handle);
    while($i=0; $i<$desired_line; i++)
        fgetcsv($handle, 1000, ",")
    

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

    我不确定这是否会占用内存或速度,但它确实起了作用。

        5
  •  0
  •   Lajnold    14 年前

    如果我理解正确,在发现错误后,您希望在某个时间点搜索特定的行。如果是这种情况,您可能会将坏行的行号存储或打印到某个地方,这取决于您所说的“通知”的含义。

    除非你 真正地 意味着你不能使用 fseek() *,您还可以在文件中存储/打印错误行开始的位置。然后你可以 FSEK() .

    *在这种情况下,如何 fseekbyline() 是否可用?