<p>下面是一个实现,它修复了sofar提出的其他方法中的一些缺陷:</p>
<ul>
<li>它不会在出现错误时丢失数据-<a href="https://stackoverflow.com/questions/5287762/how-to-insert-a-new-line-before-the-first-line-in-a-file-using-python/5287809#5287809">@kriegar's version</a>会</li>
<li>支持空文件-<a href="https://stackoverflow.com/questions/5287762/how-to-insert-a-new-line-before-the-first-line-in-a-file-using-python/5287934#5287934">^{<cd1>} version</a>不支持</li>
<li>保留原始数据:不改变尾随空白-<a href="https://stackoverflow.com/questions/5287762/how-to-insert-a-new-line-before-the-first-line-in-a-file-using-python/5287934#5287934">^{<cd1>} version</a>做</li>
<li>并且不会像<a href="https://stackoverflow.com/questions/5287762/how-to-insert-a-new-line-before-the-first-line-in-a-file-using-python/5287809#5287809">the version from net4geeks.com</a>那样读取内存中的整个文件。</li>
</ul>
<p>它模拟<code>fileinput</code>的错误处理:</p>
<pre><code>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')
</code></pre>
<p>如果可以使用<code>cat</code>实用程序复制文件,则可以使用该实用程序。可能更有效:</p>
<pre><code>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')
</code></pre>