3

我正在尝试将 PHP 代码转换为 Python,但在替换行时遇到了问题。尽管我发现使用 Python 更容易,但我完全迷失了;我可以找到要替换的行,我可以在行尾添加一些内容,但我无法在文件上再次写入该行。

file = open("cache.ucb", 'rb')
for line in file:
   if line.split('~!')[0] == ex[4]:
       line += "~!" + mask[0]
       line = line.rstrip() + "\n"
       # Write on the file here!

基本上,该文件用作~!分隔符,我读取每一行。如果该行的第一个标记~!开头ex[4],例如可以是Catbuntu,我想在该行的末尾附加mask[0],这可能是Bousie。然后我删除新行字符并在末尾添加一个。

这就是问题所在。我想按原样编写文件,但只更改该行。那可能吗?

4

4 回答 4

5

假设您使用的是 python >=2.7,以下应该可以解决问题

original = open(filename)
newfile = []
for line in original:
    if line.split('~!')[0] == ex[4]:
        line += "~!" + mask[0]
        line = line.rstrip() + "\n"
    newfile.append(line)
original.close()
amended.open(filename, "w")
amended.writeLines(newfile)
amended.close()

如果出于某种原因您使用的是 python 2.6 或更低版本,请将倒数第二行替换为:

amended.write("".join(newfile))

编辑:修复替换从问题中复制的错误,提取文件名。

于 2012-12-21T20:52:33.483 回答
2

您不能就地修改文件,至少如果您想在一行中插入字符则不能。您最终将覆盖下一行的开头。

有两种不同的方法可以做到这一点:

  1. 将文件读入内存,关闭它,然后写回新版本。
  2. 边写边写一个新的临时文件,然后把它移到原来的版本上。

那么,您如何在它们之间进行选择呢?我将尝试总结差异,按顺序排列,如果重要的话,每个差异通常都优于下面的差异(但这只是“通常”——你必须考虑自己的用例):

  • 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开始,以及互联网上的类似讨论。

于 2012-12-21T21:11:36.960 回答
1

以“wb”模式打开文件并放在file.write(line)循环的末尾。

于 2012-12-21T20:51:07.283 回答
0

您没有打开文件进行写入。

file = open("cache.ucb", 'rb')

此行打开一个文件以二进制模式读取。您还需要打开它进行写作。

尝试以写入模式打开文件,'w' 并写回该行。

或者您可以简单地在开头打开文件进行读/写,然后在循环中写入:

file = open("cache.ucb", 'a+')
于 2012-12-21T20:50:52.697 回答