从PHP文件中删除前X行

从PHP文件中删除前X行,php,performance,large-files,fgets,splfileobject,Php,Performance,Large Files,Fgets,Splfileobject,我想知道是否有人知道如何在PHP中实现这一点。我正在运行一个脚本,包括打开一个文件,取前1000行,用这些行做一些事情,然后php文件打开另一个自身实例,取下1000行,依此类推,直到到达文件末尾。我使用splfileobject,这样我就可以搜索到某一行,这样我就可以很好地将其分解为1000行块。我面临的最大问题是性能问题。我处理的文件有超过10000000行,虽然它的前10000行速度相当快,但在这一点之后,速度会出现巨大的指数级下降,我认为这只是为了达到这一点 我想做的是读取前千行,然后将

我想知道是否有人知道如何在PHP中实现这一点。我正在运行一个脚本,包括打开一个文件,取前1000行,用这些行做一些事情,然后php文件打开另一个自身实例,取下1000行,依此类推,直到到达文件末尾。我使用splfileobject,这样我就可以搜索到某一行,这样我就可以很好地将其分解为1000行块。我面临的最大问题是性能问题。我处理的文件有超过10000000行,虽然它的前10000行速度相当快,但在这一点之后,速度会出现巨大的指数级下降,我认为这只是为了达到这一点

我想做的是读取前千行,然后将它们从文件中删除,这样我的脚本就会一直读取前千行。有没有一种方法可以做到这一点,而无需将文件的其余部分读入内存。我见过的其他解决方案包括将每一行读入一个数组,然后去掉第一个X条目,但是一千万行会占用太多的内存和时间


如果有人提出了可以提高性能的解决方案或其他建议,我们将不胜感激。

不幸的是,没有真正的解决方案,因为文件总是在读取之前完全加载到主内存中

尽管如此,我还是发布了这个答案,因为这是一个可能的解决方案,但我怀疑它几乎无法提高性能。如果我错了,请纠正我

您可以使用XML将文件划分为1000行的单位。并使用PHP的DomDocument类来检索和追加数据。您可以在需要添加数据时附加子节点,并检索第一个子节点以获取前千行,如果需要,还可以删除该节点。就这样,

<document>
    <part>
        . . . 
        Thousand lines here
        . . . 
    </part>
    <part>
        . . . 
        Thousand lines here
        . . . 
    </part>
    <part>
        . . . 
        Thousand lines here
        . . . 
    </part>
    .
    .
    .
</document>

. . . 
这里有一千行
. . . 
. . . 
这里有一千行
. . . 
. . . 
这里有一千行
. . . 
.
.
.
另一种方式:


如果你真的确定要把这些部分分成整整1000行,为什么不把它们保存在一个数据库中,每1000行放在一个不同的行中呢?通过这样做,您肯定会减少文件读/写开销并提高性能

在我看来,目标是解析大量数据并将其插入数据库?如果是这样的话,我无法理解为什么使用1000行代码很重要

我想我应该一次将一大块数据(比如1MB)读入内存,然后从内存块的末尾向后扫描最后一行的结尾。一旦我有了它,我就可以保存文件位置和我拥有的额外数据(从最后一行结束到区块结束的剩余数据)。或者,只需使用fseek()将文件指针重置到文件中我发现最后一行结束的位置,使用strlen($chunk)即可轻松完成

这样,我所要做的就是通过运行explode(“\r\n”,$chunk)来分解块,并且我在一个适当大的块中拥有我需要的所有行,以便进一步处理


不建议删除文件开头的行。这会将大量数据来回移动到磁盘。

您认为查找需要花费时间吗?我注释掉了迭代行计数器的行,因此它总是在前1000行运行,并且以指数速度运行。再加上随着时间的推移,速度会呈指数级下降,唯一改变的是它所寻找的路线。寻找不应该花费指数级的时间。速度减慢的程度是什么?我们可能还想知道,当使用
SplFileObject
seek()
方法时,文件一直被读取到您要查找的位置(每一行都被读取,然后被丢弃)。它不同于
fseek()
-ing到字节偏移量。@Eric不按行搜索。每次打开文件时,都必须计算行数。存储
tell()
返回的字节偏移量或spfileobject中的任何内容。这是一个可以跳过的简单字节计数,而且速度非常快,因为PHP不必扫描/计数行结束。一旦你找到了正确的位置,你就可以开始数线了。