【问题标题】:Python: undo write to filePython:撤消写入文件
【发布时间】:2023-03-03 04:04:01
【问题描述】:

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

提前致谢!

【问题讨论】:

  • 您为什么要这样做?你能给出背景背景吗?
  • “您好,我刚刚在脚上开了一枪,最好的治疗方法是什么才能让疼痛消失?”回答?不要打自己的脚!在您知道这是您要执行的操作之前,不要将该行写到文件中。
  • @Sridhar Ratnakumar:我有大量数据要解析以生成每行包含相关信息的文件。但是,如果给定的行包含与前一行相同的信息,则需要以不同的格式编写。鉴于源数据很大,我想逐行处理。这有意义吗?
  • @Lasse V. Karlsen:是的,我知道。但我试图通过在内存中存储尽可能少的信息来找到一种方法。
  • 你确定可以在内存中保留 1 行吗?

标签: python file undo


【解决方案1】:

如前所述,您最好不要尝试撤消写入。但是,如果您真的想这样做,那很容易:

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")

只需记录要回退到的文件位置,返回到该位置,然后将文件截断到该位置。

这样做的主要问题是它不适用于流。您不能对标准输出、管道或 TCP 流执行此操作;仅限于真实文件。

【讨论】:

    【解决方案2】:

    正如其他人所指出的,这没有多大意义,最好不要写,除非你不得不。在您的情况下,您可以将“写入指针”保留在处理之后的一行。

    伪代码:

    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()。起初它似乎更容易编码,但调试起来简直就是一场噩梦。

    【讨论】:

      【解决方案3】:

      也许更好的做法是修改您的程序,以便它只在您确定要编写它时才写一行。为此,您的代码应如下所示:

      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)
      

      【讨论】:

        【解决方案4】:

        如果您跟踪行号,您可以使用以下内容:

        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 
        

        【讨论】:

        • @ennukiller:我也是这么想的,但我不太确定这是否是最好的方法。我想有时你必须做有效的事情,而不是担心什么是花哨的。
        【解决方案5】:

        尝试写入您的文件懒惰地:在您最终确定需要这样做之前不要写入。

        【讨论】:

        • 是的,这是一种选择,但我正在处理大量数据,我宁愿在内存中保留一小部分数据,直到它被刷新。
        • 在这种情况下,小子集是您正在等待写入的 一个 行。
        • 愿意!!!这就是我想做的方式,不幸的是,我有大量的数据从 subprocess.Popen 调用返回,所以我必须直接将它传送到文件。
        猜你喜欢
        • 2013-07-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-15
        • 1970-01-01
        • 2015-08-05
        • 1970-01-01
        相关资源
        最近更新 更多