Python:读取一行并写回同一行

时间:2014-05-11 22:00:28

标签: python file file-io

我正在使用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 个答案:

答案 0 :(得分:6)

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

SO中的许多问题都是尝试读取文件并立即更新。

虽然这在技术上是可行的,但这非常困难。

(文本)文件不是按行排列在磁盘上,而是按字节组织。

问题是,旧行上读取的字节数通常与新行不同,这会弄乱生成的文件。

通过创建新文件

进行更新

虽然听起来效率低,但从编程的角度来看,它是最有效的方式。

只读取文件的一面,写入另一面的另一个文件,关闭文件并复制新创建的内容。

或者在内存中创建文件,最后在关闭旧文件后再对旧文件进行书写。

答案 1 :(得分: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

有点相关:Undo a Python file readline() operation so file pointer is back in original state

只有当您的输出行保证具有相同的长度时,才会证明这种方法是合理的,例如,当您使用的文件非常庞大时,您必须对其进行修改。

在所有其他情况下,只需在内存中构建输出并立即将其写回来就会更容易,更高效。另一种选择是写入临时文件,然后删除原始文件并重命名临时文件,以便替换原始文件。