如何在3 gig文本文件中获取特定行。这些行由\ n分隔。我需要能够按需获得任何一条线。
如何做到这一点?只需要返回一行。我不想使用任何系统调用。
注意:其他地方有关于如何在bash中执行此操作的问题。我想将它与PHP等效进行比较。
更新:每条线的长度都是相同的。
答案 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()来快速获得一行。
答案 4 :(得分:0)
虽然这不是一个确切的解决方案,但是你怎么需要从3 gig文本文件中提取一行?性能是一个问题还是可以悠闲地运行? 如果你需要在不同的时间点从这个文件中抽出很多行,我肯定会建议将这些数据放入某种类型的数据库中。 SQLite可能是你的朋友,因为它非常简单但不是很好,有很多脚本/人一次访问它。