Python:读一行并写回同一行

Python:读一行并写回同一行,python,file,file-io,Python,File,File Io,我正在使用python为html制作一个模板更新程序。我读了一行,并将其与模板文件进行比较,以查看是否有任何需要更新的更改。然后,我想将任何更改(如果有)写回我刚才读到的同一行 读取文件时,我的文件指针现在位于readline()之后的下一行。我是否可以写回同一行,而不必打开两个文件句柄进行读写 下面是我想做的一段代码: cLine = fp.readline() if cLine != templateLine: # Here is where I would like to write

我正在使用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
在文本文件中就地更新行-非常困难 SO中的许多问题都试图读取文件并立即更新

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

(文本)磁盘上的文件不是按行组织的,而是按字节组织的

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

通过创建新文件进行更新 虽然听起来效率很低,但从编程的角度来看,这是最有效的方法

只需在一边读取文件,在另一边写入另一个文件,关闭文件并将新创建的内容复制到旧文件上


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

在操作系统级别,情况与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
有些相关:

只有当您的输出行保证具有相同的长度,并且您正在处理的文件非常大,因此必须对其进行适当修改时,这种方法才是合理的


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

实际上,您需要做的是读取整个文件,进行更改,然后将其全部写回。嗯,我们试图避免这种情况,但我想可能没有其他方法(至少有一个不是黑客)@jonrsharpe嗯,我不需要读取整个文件,在大文件的情况下可能不可行。但我认为没有比解析更好的选择。这是不可能的,或者至少很难在一个文件上完成。人们有时倾向于认为文件是按行组织的,而不是字节数组。这是潜在的问题m IMO.@luk32:True。对于Python问题,这种假设可能是因为文件的基本Python接口是按行组织的。或者在打开源文件并使用原始名称写入文件之前重命名源文件。