Paul Rubin <http> wrote: > You could do it "in place" in all those systems afaik, either opening > the file for both reading and writing, or using something like mmap. > Basically you'd leave the file unchanged up to line N, then copy lines > downward starting from line N+1. At the end you'd use ftrunc to > shrink the file, getting rid of the duplicate last line.
Making a new copy and renaming it when you're finished is probably both easier (don't have to keep seeking about all the time) and more reliable (doesn't leave your file corrupted if you crash half-way through). Is there a standard wossname which does this? from __future__ import with_statement from contextlib import contextmanager import os, sys, errno def fresh_file(base, mode = 'w'): """ Return a file name and open file handle for a fresh file in the same directory as BASE. """ for seq in xrange(50): try: name = '%s.new.%d' % (base, seq) fd = os.open(name, os.O_WRONLY | os.O_CREAT | os.O_EXCL) f = os.fdopen(fd, mode) return name, f except OSError, err: if err.errno == errno.EEXIST: pass else: raise raise IOError(errno.EEXIST, os.strerror(errno.EEXIST), base) @contextmanager def safely_writing(filename, mode = 'w'): """ Context manager for updating files safely. It produces a file object. If the controlled suite completes successfully, the file named by FILENAME is atomically replaced by the material written to the file object; otherwise the file is left alone. Safe in the presence of multiple simultaneous writers, in the sense that the resulting file is exactly the output of one of the writers (chosen nondeterministically). """ f = None newname = None try: newname, f = fresh_file(filename, mode) yield f f.close() f = None os.rename(newname, filename) finally: if f is not None: f.close() if newname is not None: try: os.unlink(newname) except: pass It seems like an obvious thing to want. (Extra messing about will be needed on Windows, which doesn't have proper atomic-rename semantics. Playing with the transactional filesystem stuff is left as an exercise to the interested student.) -- [mdw] -- http://mail.python.org/mailman/listinfo/python-list