代码之家  ›  专栏  ›  技术社区  ›  Ryan White

Python在读取行时截断行

  •  9
  • Ryan White  · 技术社区  · 17 年前

    file = open('myfile.txt', 'rw+')
    for line in file:
       processLine(line)
       file.truncate(line)
    

    这似乎是一个简单的问题,但我希望做得正确,而不是大量复杂的seek()和tell()调用。

    也许我真正想做的就是从文件中删除一行。

    在花了很长时间研究这个问题之后,我认为每个人都是对的,这不是一个好的做事方式。这似乎是一个非常优雅的解决方案。我要找的是类似于FIFO的东西,可以让我从文件中弹出行。

    7 回复  |  直到 17 年前
        1
  •  19
  •   jfs    6 年前

    with open('myfile.txt', 'r+') as file:
        for line in file:
            processLine(line)
        file.truncate(0)
    

    分别拆下每一行:

    lines = open('myfile.txt').readlines()
    
    for line in lines[::-1]: # process lines in reverse order
        processLine(line)
        del lines[-1]  # remove the [last] line
    
    open('myfile.txt', 'w').writelines(lines)
    

    import fileinput
    
    for line in fileinput.input(['myfile.txt'], inplace=1):
        try: processLine(line)
        except Exception:
             sys.stdout.write(line) # it prints to 'myfile.txt'
    

    总的来说,正如其他人所说,你想做什么是个坏主意。

        2
  •  9
  •   nosklo    17 年前

    你不能

    文本文件是连续的,因为文本文件中的行可以是任意长度。

    假设您有一个包含以下3行的文件;

    'line1\nline2reallybig\nline3\nlast line'
    

    要删除第二行,必须移动磁盘中第三行和第四行的位置。唯一的方法是将第三行和第四行存储在某个位置,截断第二行的文件,然后重写丢失的行。

    如果知道文本文件中每一行的大小,可以使用 .truncate(line_size * line_number)

        3
  •  6
  •   sykora    17 年前

    最好在文件中保留一个索引,这样就可以从上次停止的位置开始,而不会破坏文件的一部分。类似这样的方法会奏效:

    try :
        for index, line in enumerate(file) :
            processLine(line)
    except :
        # Failed, start from this line number next time.
        print(index)
        raise
    
        4
  •  4
  •   Imran    17 年前

    在读取时截断文件似乎有点极端。如果您的脚本有一个不会导致错误的bug怎么办?在这种情况下,您需要在文件开头重新启动。

    让脚本打印它中断的行号,并将行号作为参数,以便告诉它从哪一行开始处理,怎么样?

        5
  •  4
  •   zoul    17 年前

    truncate 截断 剪切从当前位置到文件结尾的所有内容。这就是标准Python的工作原理

    其次,我不确定在使用 for in-place filtering ,这意味着以后删除处理过的行应该相当简单。

    顺便说一句,我不认识巨蟒,请不要客气。

        6
  •  2
  •   Community Mohan Dere    9 年前

    How can I run the first process from a list of processes stored in a file and immediately delete the first line as if the file was a queue and I called "pop"?

    我使用它的方式如下:

      import os;
    
      tasklist_file = open(tasklist_filename, 'rw');  
      first_line = tasklist_file.readline();
      temp = os.system("sed -i -e '1d' " + tasklist_filename); # remove first line from task file;
    

    在mac电脑上试了一下,果然奏效了。

        7
  •  2
  •   Matthew Fairleaf    9 年前

    这就是我用于基于文件的队列的方法。它返回第一行并用其余的重写文件。完成后,将返回“无”:

    def pop_a_text_line(filename):
        with open(filename,'r') as f:
            S = f.readlines()
        if len(S) > 0:
            pop = S[0]
            with open(filename,'w') as f:
                f.writelines(S[1:])
        else:
            pop = None
        return pop