Python:读取一行并写回该行

3 投票
2 回答
5108 浏览
提问于 2025-04-18 06:14

我正在用Python制作一个HTML模板更新器。我会读取一行内容,并把它和模板文件进行比较,看看是否有需要更新的地方。如果有变化,我想把这些变化写回到我刚刚读取的那一行。

在读取文件时,我的文件指针现在已经移动到下一行了,因为我用了一次readline()。有没有办法在不打开两个文件句柄(一个用于读取,一个用于写入)的情况下,把内容写回到同一行呢?

下面是我想要做的代码片段:

cLine = fp.readline()
if cLine != templateLine:
   # Here is where I would like to write back to the line I read from
   # in cLine

2 个回答

2

在操作系统层面,事情和我们在Python中看到的有点不同。在Python里,文件看起来就像是一串字符串,每个字符串的长度可以随意变化,所以似乎可以很简单地把某一行换成别的内容,而不影响其他行:

l = ["Hello", "world"]
l[0] = "Good bye"

但实际上,任何文件都是一串字节流,字符串是一个接一个排列的,没有任何“填充”。所以你只能在原地覆盖数据,如果新字符串的长度和原字符串完全相同,否则就会把后面的行覆盖掉。

如果你的处理方式保证不会改变字符串的长度,那么你可以“倒回”到行的开头,用新数据覆盖这一行。下面的脚本就是在原地把文件中的所有行转换为大写:

def eof(f):
    cur_loc = f.tell()
    f.seek(0,2)
    eof_loc = f.tell()
    f.seek(cur_loc, 0)
    if cur_loc >= eof_loc:
        return True
    return False

with open('testfile.txt', 'r+t') as fp:

    while True:
        last_pos = fp.tell()
        line = fp.readline()
        new_line = line.upper()
        fp.seek(last_pos)
        fp.write(new_line)
        print "Read %s, Wrote %s" % (line, new_line)
        if eof(fp):
            break

有点相关的内容:撤销Python的readline()操作,让文件指针回到原来的状态

这种方法只有在你的输出行长度保证相同的情况下才合理使用,比如说,你正在处理的文件非常大,所以必须在原地修改。

在其他情况下,直接在内存中构建输出,然后一次性写回去会更简单、更高效。另一种选择是先写入一个临时文件,然后删除原文件,再把临时文件重命名为原文件,这样就替换了原文件。

7

在文本文件中更新行 - 非常困难

在StackOverflow上,有很多问题都在讨论如何同时读取文件并更新它。

虽然从技术上讲这是可能的,但实际上非常困难。

文本文件在磁盘上的存储方式是按字节,而不是按行来组织的。

问题在于,旧行所占的字节数和新行所占的字节数往往是不同的,这样就会搞乱最终的文件。

通过创建新文件来更新

虽然听起来效率不高,但从编程的角度来看,这是最有效的方法。

你可以先从一个文件中读取内容,然后把它写入另一个文件,最后关闭这两个文件,再把新文件的内容复制到旧文件上。

或者,你也可以在内存中创建一个文件,等到关闭旧文件后再把内容写回去。

撰写回答