您不能就地修改文件,至少如果您想在一行中插入字符则不能。您最终将覆盖下一行的开头。
有两种不同的方法可以做到这一点:
- 将文件读入内存,关闭它,然后写回新版本。
- 边写边写一个新的临时文件,然后把它移到原来的版本上。
那么,您如何在它们之间进行选择呢?我将尝试总结差异,按顺序排列,如果重要的话,每个差异通常都优于下面的差异(但这只是“通常”——你必须考虑自己的用例):
2 不需要将整个内容保存在内存中。如果你的文件有 20GB 长,这显然是一个巨大的胜利;如果它是 16KB,没关系。
2 使整个操作原子化。即使它中途失败,或者其他进程在您更改文件时尝试读取文件,任何人都无法看到一些无效的半修改文件;他们将看到原始文件或新文件。
2 需要一些可用磁盘空间(因为暂时同时有两个文件副本)。
如果您同时关心 Windows 和 POSIX,那么 2 是一个巨大的痛苦。
如果原始文件和临时目录位于不同的文件系统上,则 2 可能涉及跨文件系统复制,除非您对此非常小心。
如果以上两个都不是问题,则 2 更简单。
Drakekin 的回答告诉你如何做#1。
如果您不关心 Windows 或跨文件系统问题,请执行以下操作 #2:
infile = open("cache.ucb", 'rb')
outfile = tempfile.NamedTemporaryFile(delete=False)
for line in infile:
if line.split('~!')[0] == ex[4]:
line += "~!" + mask[0]
line = line.rstrip() + "\n"
outfile.write(line)
infile.close()
os.rename(outfile.name, "cache.ucb")
outfile.close()
dir=os.path.dirname(original path)
您可以通过例如传递给构造函数来解决跨文件系统问题NamedTemporaryFile
,但前提是您确定始终有权在原始文件旁边创建一个新文件(这并不总是得到保证,只是因为您有重写原始文件的权限——UNIX 权限、Windows ACL、OS X 沙箱等都给出了可能是错误的方法)。
要解决 Windows 问题……好吧,从Is an atomic file rename (with overwrite) possible on Windows开始,以及互联网上的类似讨论。