替换文件中的一行而不重写整个文件(在PHP中)

时间:2012-04-05 14:45:01

标签: php fopen fwrite fread

假设我有一个适度大小的文本文件(~850kb,10,000+行)

我想替换文件中传播的特定行(或几行)。

目前执行此操作的方法包括重写整个文件。我使用的当前方法是逐行读取整个文件,写入.tmp文件,一旦完成,我将tmp文件重命名为()为原始源文件。

它有效,但速度很慢。当然,随着文件的增长,执行时间也会增长。

是否有另一种方式(使用PHP)完成工作而不必在每次需要更换或删除一行或两行时重写整个文件?

谢谢!我环顾四周,无法在stackoverflow上找到答案。

2 个答案:

答案 0 :(得分:4)

如果替换的大小与原始行的大小完全相同,那么您只需在文件中的该位置fwrite()即可。但如果它的长度不同(较短 OR 较长),则必须重写替换后文件的部分。

没有办法解决这个问题。较短的“新”行会在文件中留下间隙,较长的“新”行会覆盖下一行的第一部分。

基本上,你问是否可以在另一块板的中间插入一块木头,而不必移动原板。

答案 1 :(得分:2)

你不能,因为文件存储在公共文件系统上的方式。文件总是占用磁盘空间的一个或多个“块”,其中块的大小为4096字节。具有一个字节数据的文件仍将占用一个整块(消耗4096个字节的可用磁盘空间),而一个4097字节的文件将占用两个块(占用8192个字节)。

如果从文件中删除一个字节,则在其占用的一个块中将存在一个字节的间隙,这是无法存储在磁盘上的。您必须将所有其他字节一个字节移到文件的开头,这将影响当前和所有后续块。

反过来说,在块的中间添加字节,显示了同样的问题:你将有一个或多个字节不再适合4096字节,所以他们必须转移到下一个块,依此类推,直到文件的末尾(和所有块)都已到达。

在块中唯一可以包含非占用字节的位置是在形成文件的最后一个块的末尾。