7

我想知道是否有人知道如何在 PHP 中做到这一点。我正在运行一个脚本,该脚本涉及打开一个文件,获取前 1000 行,用这些行做一些事情,然后 php 文件打开它自己的另一个实例以获取接下来的 1000 行,依此类推,直到它到达文件的末尾. 我正在使用 splfileobject 以便我可以寻找到某一行,这使我可以很好地将其分解为 1000 行块。我遇到的最大问题是性能。我正在处理具有超过 10,000,000 行的文件,虽然它在前 10,000 行左右的速度非常快,但在那之后会出现巨大的指数放缓,我认为只需要寻找到那一点即可。

我想做的是读取前一千行,然后从文件中删除它们,以便我的脚本始终读取前一千行。有没有办法在不将文件的其余部分读入内存的情况下做到这一点。我见过的其他解决方案包括将每一行读入一个数组,然后删除前 X 个条目,但是有一千万行会占用太多内存和时间。

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

4

2 回答 2

1

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

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

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

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

另一种方式 :

如果您真的确定要将这些部分分成 1000 行,为什么不将其保存在数据库中,每 1000 行位于不同的行中呢?通过这样做,您肯定会减少文件读/写开销并提高性能。

于 2012-03-26T18:55:47.593 回答
1

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

我想我会通过一次将一大块数据(比如 1 MB)读取到内存中来接近它,然后从内存块的末尾向后扫描以查找最后一行的结尾。一旦我有了它,我就可以保存文件位置和我拥有的额外数据(从最后一行结束到块结束的剩余部分)。或者,只需使用 fseek() 将文件指针重置为我在文件中找到最后一行结尾的位置,使用 strlen($chunk) 轻松完成。

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

不建议从文件开头删除行。这将在磁盘上来回移动大量数据。

于 2012-03-28T20:36:32.390 回答