Вот реализация, которая исправляет некоторые недостатки других представленных подходов:
Имитирует обработку ошибок fileinput
:
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')
Вы можете использовать утилиту cat
, если она доступна для копирования файлов. Это может быть более эффективным:
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')