I know the normal way to write to a file by rewriting the lines except the ones to delete. But I want to know is there an efficient way to delete or update a line in place or append at the last in a file using file pointers in Python.
Asked
Active
Viewed 1,251 times
1 Answers
0
Appending to the end is easy:
with open('somefile', 'a') as f:
f.write(line) # Or with print to add a newline for you, print(line, file=f)
In the middle, you're generally stuck; unless the new line is exactly the same length as the existing line, you'll have to move all the data after that line around to make it work, and that risks data corruption if anything (including non-software issues like a power outage) goes wrong. In that case, just write a new file, and use os.replace
to atomically replace the old file with the new file after the new file is written out completely.

ShadowRanger
- 143,180
- 12
- 188
- 271
-
I want to know if there's a way to delete a line without rewriting the whole file except that line. – Paras Karnawat Mar 23 '19 at 03:29
-
@ParasKarnawat: Unless the line is at the end of the file, you're going to have to rewrite every byte from that line onward. And as I said, doing so in a crash-safe way is effectively impossible (barring file system transactional write APIs, which Python doesn't give you access to even if they exist), so rewriting is the only way to do this safely. – ShadowRanger Mar 23 '19 at 03:39
-
@ParasKarnawat: There are [solutions that work for replacing lines at the end of a file](https://stackoverflow.com/a/33811809/364696), where at least you're not stuck with a massive copy down operation, but even there you risk data corruption if you're interrupted in the middle. – ShadowRanger Mar 23 '19 at 03:43
-
Can you explain that way, I just want to try it and implement it to see how it works? – Paras Karnawat Mar 23 '19 at 03:44
-
@ParasKarnawat: Which way? The copy down approach? Easiest way would be to `mmap.mmap` the file, find the offsets of the beginning and end of the line to remove, then do `mm.move(begin, end, len(mm) - end)`, then either use `mmap.resize` (if your OS supports it) or close it and `seek` the original file object with `f.seek(-numbytestoremove, io.SEEK_END)` and call `f.truncate()` to remove the extraneous bytes. It's not string friendly (`mmap` is bytes oriented), but `mmap` makes it much easier to safely move data from one part of the file to another even with overlapping ranges. – ShadowRanger Mar 23 '19 at 03:54