我有一个csv文件,记录被排序在第一个字段。我设法生成一个函数,通过该文件进行二分搜索,使用fseek通过文件进行随机访问。php文件随机访问和文件保存对象
但是,这仍然是一个非常缓慢的过程,因为当我寻找某个文件位置时,实际上我需要向左看,寻找\ n字符,因此我可以确保我正在读整行(整个行被读取,我可以检查上面提到的第一个字段值)。
这里是返回一个包含字符在位置的直线x功能:
function fgetLineContaining($fh, $x) {
if($x 125145411) // 12514511 is the last pos in my file
return "";
// now go as much left as possible, until newline is found
// or beginning of the file
while($x > 0 && $c != "\n" && $c != "\r") {
fseek($fh, $x);
$x--; // go left in the file
$c = fgetc($fh);
}
$x+=2; // skip newline char
fseek($fh, $x);
return fgets($fh, 1024); // return the line from the beginning until \n
}
虽然这是按预期工作,我不得不悲哀的是我的CSV文件〜1.5Mil行,这些左派的追求正在减缓。
有没有更好的方法来寻找一个文件中的位置x?
另外,如果一个类的对象可以保存到一个文件而不需要序列化,那么它会好得多,从而能够逐个对象地读取文件。 PHP支持吗?
感谢
另外,还有另外一个想法出现在我脑海里 - 如何对文件进行采样 - 从文件中每1000个条目取一个条目并将其存储到数组中。这将产生1500个元素数组,我可以进行二分法搜索,在所需的线上得到粗略的近似值。然后我可以加载剩余的1000个元素并对它们进行二分搜索。这是否做同样的事情? – hummingBird 2010-10-29 21:18:05
你在这个文件上执行什么样的搜索?文件是否经常更改?如果您要在同一个文件上执行多次搜索,将数据加载到SQLite数据库并搜索数据库可能会快很多。 – kijin 2010-10-29 21:31:30
如果你知道一条平均线的长度,你可以稍微返回一点,做'fgets()'来将指针与前一行的末尾或者之前的几行对齐。二进制搜索的目的应该足够好。 – kijin 2010-10-29 21:32:45