Python:撤销对文件的写入

3
什么是撤销文件写入的最佳方法?如果我正在循环中逐行写入,并且想要撤销先前的写入并替换为其他内容,我该如何操作?有什么想法吗?
提前感谢!

1
为什么你想要这样做?你能给出一些背景上下文吗? - Sridhar Ratnakumar
2
嗨,我刚才自己把脚给枪伤了,有什么最好的方法可以治疗并减轻疼痛吗?回答是什么?不要向脚文件写入代码行,除非你确定这是你想要做的事情。 - Lasse V. Karlsen
@Sridhar Ratnakumar:我有大量数据需要解析,以生成每行相关信息的文件。但是,如果给定行包含与上一行相同的信息,则需要以不同的格式编写。鉴于源数据非常庞大,我想逐行处理它。这样做有意义吗? - aspade
@aspade:请不要在自己的问题下评论。请更新您的问题并提供相关信息。 - S.Lott
@Glenn Maynard -- 一个明确的问题比一堆来回评论更清晰。问题应该独立存在,这样其他人就可以搜索、阅读和学习。无休止的评论来完善问题会使其难以搜索和无用。 - S.Lott
显示剩余3条评论
5个回答

5

正如其他人所指出的,这并没有太多意义,最好在必要时再进行编写。在您的情况下,您可以将“写入指针”保持在处理的一行之后。

伪代码:

previousItem = INVALID
for each item I:
  is I same as previousItem?
    then update previousItem with I
    else
      write previousItem to file
      previousItem = I
write previousItem to file

如您所见,previousItem 是唯一保存在内存中的项目,并在需要时更新为“accumulate”。只有当下一个项目不“与之相同”时,才将其写入文件。
当然,您可以回滚文件光标,仅跟踪上一行开始的字节偏移量,然后在重写之前执行fseek()。起初,这似乎更简单易懂,但它是一个完全无法调试的噩梦。

5

如前所述,最好不要尝试撤销写入操作。但如果你真的想这么做,也很容易:

import os
f = open("test.txt", "w+")
f.write("testing 1\n")
f.write("testing 2\n")
pos = f.tell()
f.write("testing 3\n")

f.seek(pos, os.SEEK_SET)
f.truncate(pos)
f.write("foo\n")

只需记录要倒带的文件位置,将其定位回去并截断文件到该位置即可。

这样做的主要问题是它无法在流上工作。您不能对stdout、管道或TCP流进行此操作,只能对真实文件执行此操作。


4
尽量使用“懒惰”方式写入文件:只有在确实需要时才将其写入。

是的,那是一个选项,但我正在处理大量数据,我宁愿在内存中保留一小部分数据,直到刷新为止。 - aspade
在这种情况下,小的子集是你正在等待编写的*一行代码。 - S.Lott
非常愿意!!!这是我想要的方式,但不幸的是,我从subprocess.Popen调用中返回了大量数据,所以我必须直接将其管道传输到文件。 - gunslingor

0
如果您跟踪行号,可以使用类似以下的代码:
from itertools import islice 
def seek_to_line(f, n): 
    for ignored_line in islice(f, n - 1): 
        pass   # skip n-1 lines 


f = open('foo') 
seek_to_line(f, 9000)    # seek to line 9000 


# print lines 9000 and later 
for line in f: 
    print line 

@ennuikiller:我也是这么想的,但我不确定那是否是最好的方法。我想有时候你得做能用的而不是担心是否花哨。 - aspade

0
也许更好的做法是修改您的程序,以便仅在确定要写入时才写入一行。为此,您的代码应该类似于:
to_write = ""
for item in alist:
  #Check to make sure that I want to write
  f.write(to_write)
  to_write = ""
  #Compute what you want to write.
  to_write = something

#We're finished looping so write the last part out
f.write(to_write)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接