Python: undo writing to file
What's the best way to undo writing to a file? If I go through the loop and write one line at a time, and I want to undo the previous entry and replace it with something else, how do I do that? Any ideas?
Thanks in advance!
as others have pointed out, it doesn't make a lot of sense, much better not to write until you have to. in your case, you can leave the "write pointer" one line for your processing.
pseudocode:
previousItem = INVALID
for each item I:
is I same as previousItem?
then update previousItem with I
else
write previousItem to file
previousItem = I
write previousItem to file
as you can see, it previousItem
is the only item stored in memory and it is updated to "accumulate" as needed. it is only written to the file when the next is not "the same" as the one.
of course you can actually rollback the cursor, just keep track of the byte offset where the last line was started and then execute before rewriting fseek()
. it would have been easier to code at first, but it was a complete debugging nightmare.
Try to write to your files lazily: don't write until you are sure you need to do it.
As mentioned, you better not try to undo the recording. If you really want it, it's easy enough:
import os
f = open("test.txt", "w+")
f.write("testing 1\n")
f.write("testing 2\n")
pos = f.tell()
f.write("testing 3\n")
f.seek(pos, os.SEEK_SET)
f.truncate(pos)
f.write("foo\n")
Just write down the position of the file to rewind, request it, and truncate the file to that position.
The main problem with this is that it doesn't work in threads. You cannot do this for stdout, or for a TCP or TCP stream; for a real file only.
If you are keeping track of line numbers, you can use something like this:
from itertools import islice
def seek_to_line(f, n):
for ignored_line in islice(f, n - 1):
pass # skip n-1 lines
f = open('foo')
seek_to_line(f, 9000) # seek to line 9000
# print lines 9000 and later
for line in f:
print line
Perhaps your best bet would be to change your program so that it only writes a line if you are sure you want to write it. To do this, your code will look something like this:
to_write = ""
for item in alist:
#Check to make sure that I want to write
f.write(to_write)
to_write = ""
#Compute what you want to write.
to_write = something
#We're finished looping so write the last part out
f.write(to_write)