使用PHP在一个巨大的文件中获取一行

时间:2010-05-08 12:33:34

标签: php

如何在3 gig文本文件中获取特定行。这些行由\ n分隔。我需要能够按需获得任何一条线。

如何做到这一点?只需要返回一行。我不想使用任何系统调用。

注意:其他地方有关于如何在bash中执行此操作的问题。我想将它与PHP等效进行比较。

更新:每条线的长度都是相同的。

5 个答案:

答案 0 :(得分:8)

如果没有为文件保留某种索引,则需要读取所有索引,直到遇到x个字符为\ n的字符。我看到nickf刚刚发布了一些方法,所以我不会重复它。

要以有效的方式重复执行此操作,您需要构建索引。为某些(或所有)行号存储一些已知文件位置,然后您可以使用fseek来搜索到正确的位置。

编辑:如果每一行的长度相同,则不需要索引。

$myfile = fopen($fileName, "r");
fseek($myfile, $lineLength * $lineNumber);
$line = fgets($myfile);
fclose($myfile);

此示例中的行号为0,因此您可能需要先减去一行。行长度包括\n字符。

答案 1 :(得分:8)

对这个问题几乎没有讨论,也没有提到应该如何引用“一行”(数字,其中的某些值等),所以下面只是猜测你想要什么

如果你不反对使用一个对象(可能是'太高级别',并且希望通过偏移引用该行),那么SplFileObject(从PHP 5.1.0开始提供)可以使用。请参阅以下基本示例:

$file = new SplFileObject('myreallyhugefile.dat');
$file->seek(12345689); // seek to line 123456790
echo $file->current(); // or simply, echo $file

该特定方法(seek)需要逐行扫描文件。但是,如果你说所有的行都是相同的长度,那么你可以使用fseek来获得你想去的地方更快,更快

$line_length = 1024; // each line is 1 KB line
$file->fseek($line_length * 1234567); // seek lots of bytes
echo $file->current(); // echo line 1234568

答案 2 :(得分:1)

我能想到的唯一方法就是这样:

function getLine($fileName, $num) {
    $fh = fopen($fileName, 'r');

    for ($i = 0; $i < $num && ($line = fgets($fh)); ++$i);

    return $line;
}

答案 3 :(得分:1)

你说每一行都有相同的长度,所以你可以使用fopen()和fseek()来快速获得一行。

http://ch2.php.net/manual/en/function.fseek.php

答案 4 :(得分:0)

虽然这不是一个确切的解决方案,但是你怎么需要从3 gig文本文件中提取一行?性能是一个问题还是可以悠闲地运行? 如果你需要在不同的时间点从这个文件中抽出很多行,我肯定会建议将这些数据放入某种类型的数据库中。 SQLite可能是你的朋友,因为它非常简单但不是很好,有很多脚本/人一次访问它。