2009-09-25 105 views
2

撤消写入文件的最佳方法是什么?如果我正在经历一个循环并一次写一行,并且我想撤消之前的写作并将其替换为其他内容,那么我该怎么做呢?有任何想法吗?Python:撤消写入文件

在此先感谢!

+1

你为什么要这样做?你能给一个背景环境吗? – 2009-09-25 19:08:14

+2

“嗨,我只是在脚下开枪自杀,治疗这种疼痛最好的方法是什么?”回答?不要将自己踢在脚下!除非您知道这是您想要做的事,否则不要将该行写出到文件中。 – 2009-09-25 19:14:53

+0

@Sridhar Ratnakumar:我有大量的数据解析来生成一个文件,每行都有相关信息。但是,如果给定的行包含与前一行相同的信息,则需要以不同的格式写入。鉴于源数据非常庞大,我想逐行处理它。这有意义吗? – aspade 2009-09-25 19:18:21

回答

4

尝试写入您的文件lazily:不要写,直到你终于确定你需要做到这一点。

+0

是的,那是一种选择,但我正在处理大量数据,我宁愿将它的一小部分保留在内存中,直到它被刷新。 – aspade 2009-09-25 19:10:22

+0

在这种情况下,小子集是您等待写入的*一行*。 – 2009-09-25 20:22:46

+0

会爱上!!!这是我想要做的方式,不幸的是我有一个来自subprocess.Popen调用的数据集合,因此我必须将其直接传递给文件。 – gunslingor 2018-01-09 18:33:18

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 
+0

@ennuikiller:我也这么想,但我不太确定这是否是最好的方法。我想有时候你必须做一些有用的事情,而不必担心什么是幻想。 – aspade 2009-09-25 19:13:43

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) 
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是唯一的项目保存在内存中,并且它的更新会根据需要“收集”。它只是写入文件,当下一个不是“一样”那一个。

当然,您可以真正回滚文件光标,只记录最后一行开始处的字节偏移量,然后在重写之前执行fseek()。起初编写起来似乎更简单,但调试却是一场完全的噩梦。

4

如上所述,您最好不要试图撤消写入。如果你真的想这样做,但是,它很容易做到:

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流;只有一个真实的文件。