Here's an implementation that fixes some deficiencies in other approaches presented sofar:
It mimics fileinput
's error handling:
import os
def prepend(filename, data, bufsize=1<<15):
# backup the file
backupname = filename + os.extsep+'bak'
try: os.unlink(backupname) # remove previous backup if it exists
except OSError: pass
os.rename(filename, backupname)
# open input/output files, note: outputfile's permissions lost
with open(backupname) as inputfile, open(filename, 'w') as outputfile:
# prepend
outputfile.write(data)
# copy the rest
buf = inputfile.read(bufsize)
while buf:
outputfile.write(buf)
buf = inputfile.read(bufsize)
# remove backup on success
try: os.unlink(backupname)
except OSError: pass
prepend('file', '0 line\n')
You could use cat
utility if it is available to copy the files. It might be more efficient:
import os
from subprocess import PIPE, Popen
def prepend_cat(filename, data, bufsize=1<<15):
# backup the file
backupname = filename + os.extsep+'bak'
try: os.unlink(backupname)
except OSError: pass
os.rename(filename, backupname)
# $ echo $data | cat - $backupname > $filename
with open(filename, 'w') as outputfile: #note: outputfile's permissions lost
p = Popen(['cat', '-', backupname], stdin=PIPE, stdout=outputfile)
p.communicate(data)
# remove backup on success
if p.poll() == 0:
try: os.unlink(backupname)
except OSError: pass
prepend_cat('file', '0 line\n')