Python:读一行并写回同一行
我正在使用python为html制作一个模板更新程序。我读了一行,并将其与模板文件进行比较,以查看是否有任何需要更新的更改。然后,我想将任何更改(如果有)写回我刚才读到的同一行 读取文件时,我的文件指针现在位于readline()之后的下一行。我是否可以写回同一行,而不必打开两个文件句柄进行读写 下面是我想做的一段代码: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
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接口是按行组织的。或者在打开源文件并使用原始名称写入文件之前重命名源文件。