<p>通常不能在文件中间插入。*</p>
<p>一般的解决方案是复制到一个新文件,在复制过程中插入,然后将新文件移到旧文件上。例如:</p>
<pre><code>with tempfile.NamedTemporaryFile('w', delete=False) as outfile:
with open(inpath) as infile,
for line in infile:
outfile.write(line)
if needs_inserting_after(line):
outfile.write(stuff_to_insert_after(line))
os.replace(outfile.name, inpath)
</code></pre>
<p>注意,<a href="https://docs.python.org/3/library/os.html#os.replace" rel="nofollow">^{<cd1>}</a>在python2.7中不存在。{2}如果你不在乎的话,^你就不用了。如果您这样做,我强烈建议您在PyPI上寻找一个<code>os.replace</code>的后端口;至少有两个。否则,你就得学习Windows上的独占锁和原子移动带来的混乱。在</p>
<p>还有一些更高级别的库可以为您打包整个过程。(我写了一个名为<a href="https://github.com/abarnert/fatomic/" rel="nofollow">^{<cd4>}</a>的代码,我认为这是一个不错的示例代码,但我不确定我是否会信任它来编写没有更多测试的产品代码。我相信如果你搜索PyPI,你可以找到其他替代品。)</p>
<hr/>
<p>当然还有其他选择:</p>
<p>您可以将原始文件移动到备份路径,然后以正常路径将其复制到新文件中,而不是在临时路径复制到新文件,然后再移动。这样做的缺点是,如果中途失败,会留下半个文件,但好处是不需要处理Windows上的独占锁问题。这实际上就是<a href="https://docs.python.org/3/library/fileinput.html#fileinput.FileInput" rel="nofollow">^{<cd5>}</a>和{<cd6>}自动为您实现的功能。在</p>
<p>你可以把整个文件读入内存,在内存中处理,然后把整个文件写出来。这样做的好处是非常简单,不需要任何额外的文件,这意味着如果任何人有你的文件的文件句柄(而不是路径名),他们会在你完成后看到新版本。但最后一个可能是不利因素。当然,这意味着您需要足够的内存来同时保存所有数据。在</p>
<p>最后,在写入N个字节之前,您总是可以将整个文件从当前位置上移N个字节。这有上述两种方法的大部分优点,但也比较混乱和缓慢。在</p>
<hr/>
<p>为什么我在那里说“一般”?好吧,最终,文件系统必须有某种方法在文件的中间插入一个新的块。有些文件系统会向用户公开这一点。一些旧的平台曾经有用户级的功能,比如苹果上的“随机访问文本文件”【ProDOS或者我在虚拟机中忘记的东西。所以,你不能在文件的中间插入是不正确的。你关心的每一件事都是如此。</sub></p>