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!

+2


source to share


5 answers


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.

+5


source


Try to write to your files lazily: don't write until you are sure you need to do it.



+4


source


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.

+4


source


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 

      

0


source


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)

      

0


source







All Articles