Let's take your example. Your first file looks like this (od output).
Since you're already reading and writing every byte, you might as well use another file. There's no additional I/O cost, just disk space.
You could potentially rewrite every byte in the first file by reading a block, and writing the new block. But that means during the operation your file is inconsistent. If the program were to crash, you'd have a file that was half old and half new.
If you leave them the same length, then it should be possible to a replacement write. Uncommon, but we should be able to find an example.
0000000 a d \n 1 a \n 2 b \n 3 c \n . . . \nYou say you want it to look like this afterward:
0000000 1 0 \n 0 \n 2 b \n 4 5 \n . . . \nSee that the shorter second line means you're going to have to rewrite every byte that follows in the file since you've shifted the positions. You can't rewrite just the line that has changed. That's the advantage of a database with fixed-length fields. They can be rewritten in place cheaply.
Since you're already reading and writing every byte, you might as well use another file. There's no additional I/O cost, just disk space.
You could potentially rewrite every byte in the first file by reading a block, and writing the new block. But that means during the operation your file is inconsistent. If the program were to crash, you'd have a file that was half old and half new.
If you leave them the same length, then it should be possible to a replacement write. Uncommon, but we should be able to find an example.