2012-03-26 64 views
7

我想知道是否有人知道如何在PHP中完成此操作。我正在运行一个脚本,它涉及到打开一个文件,取第1000行,用这些行做一些事情,然后php文件打开另一个自己的实例,以获取下一千行,直到它到达文件末尾。我使用的是splfileobject,这样我就可以找到一条特定的路线,这使我能够很好地将它分解为1000行。我遇到的最大问题是性能问题。我正在处理的文件数量超过10,000,000行,虽然它的前10000行很快,但在这一点之后,我认为只需要寻找那一点就会出现巨大的指数级放缓。从文件中删除第一个X行PHP

我想要做的是读取第一千行,然后从文件中删除它们,以便我的脚本始终读取第一千行。有没有办法做到这一点,而无需将文件的其余部分读入内存。我看到的其他解决方案包括将每行读入一个数组,然后删除第一个X条目,但有一千万条线路会消耗太多的内存和时间。

如果任何人有解决方案或其他建议,可以加快性能,将不胜感激。

+0

你*想*时间正在寻求? – salathe 2012-03-26 18:24:01

+0

我评论了迭代行计数器的行,以便它始终运行前1000行,并且它以更快的速度运行。此外,随着它的进展,这个速度会呈指数级下降,唯一改变的就是它寻求的路线。 – 2012-03-26 18:27:48

+0

寻求不应该*指数*更多的时间。放缓的规模是什么? – salathe 2012-03-26 18:30:42

回答

1

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

不过,我发布了这个答案,因为这是一个可能的解决方案,但我怀疑它几乎没有提高性能。纠正我,如果我错了。

您可以使用XML将文件分成1000行的单元。并使用DomDocument类的PHP来检索和追加数据。如果你想添加数据并检索第一个子项以获得第一千行,并删除节点,可以追加子项。就像这样:

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

另一种方式:

如果你真的肯定打破段成正是1000行你为什么不与每1000保存在数据库中不同行?通过这样做,您肯定会减少文件读/写开销并提高性能。

1

在我看来,目标是解析大量的数据并将其插入数据库?如果是这样,我不明白为什么使用1000条线很重要?

我想我只是通过将一大块数据(比如说1 MB)一次读入内存来处理它,然后从最后一行结尾的内存块尾部向后扫描。一旦我有了这些,我就可以保存文件位置和额外的数据(从最后一行结束到结束块剩下的部分)。或者,只需使用fseek()将文件指针重置到我发现最后一行结束的文件中的哪个位置,轻松使用strlen($ chunk)即可完成。

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

不建议从文件开头删除行。这将会将大量的数据来回拖入磁盘。