Replacing a line in a file without overwriting the entire file (in PHP)

Suppose I have a moderate sized text file (~ 850kb, 10,000+ lines)

And I want to replace a specific line (or several) common among the file.

Current methods for doing this involve rewriting the entire file. The current method I'm using is reading through the whole file line by line, writing to a .tmp file, and once I'm done, I will rename () the tmp file to my original source file.

It works, but it is slow. And of course, as the file grows, so will the runtime.

Is there another way (using PHP) to get the job done without having to rewrite the entire file every time a line or two needs to be replaced or deleted?

Thank! I looked around and couldn't find an answer to this question on stackoverflow.

+3


source to share


2 answers


If the EXACTLY replacement is the same size as the original line, you can just fwrite()

at that location in the file and you're good. But if it is a different length (shorter OR longer), you will have to rewrite the part of the file that appears AFTER the replacement.

There is no way around this. Shorter "new" lines will leave a space in the file, and longer "new" lines will overwrite the first part of the next line.



Basically, you are asking if it is possible to insert a piece of wood in the middle of another board without moving the original board.

+3


source


You cannot, due to the fact that files are stored on regular file systems. A file always occupies one or more "blocks" on disk, where the block size is, for example, 4096 bytes. A file with one byte of data will still occupy one whole block (consuming 4096 bytes of free disk space), and a file of 4097 bytes will take two blocks (occupying 8192 bytes).

If you remove one byte from the file, it will have one byte space in one of the blocks, which cannot be saved to disk. You must move all other bytes one byte to the beginning of the file, which will affect the current and all subsequent blocks.



Another way of adding bytes in the middle of a block shows the same problem: you will have one or more bytes that no longer fit into 4096 bytes, so they will have to go to the next block, etc., until the end of the file (and all blocks).

The only place you can have unallocated bytes in a block is at the end of the last block that forms the file.

+2


source







All Articles