Python会在读取时截断行

时间:2009-02-08 06:34:53

标签: python file-io

我有一个应用程序从文件中读取行,并在读取每行时运行其魔法。一旦读取并正确处理了该行,我想从文件中删除该行。已保留已删除行的备份。我想做点什么

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

这似乎是一个简单的问题,但我想做的不错,而不是一大堆复杂的seek()和tell()调用。

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

在这个问题上花了很长时间后我决定每个人都可能是正确的,这不是一个好办法。它似乎是如此优雅的解决方案。我正在寻找的东西类似于FIFO,它只会让我从文件中弹出行。

7 个答案:

答案 0 :(得分:17)

完成后删除所有行:

with open('myfile.txt', 'rw+') 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'

总的来说,正如其他人已经说过你想要做的事情一个坏主意。

答案 1 :(得分:8)

你不能。在当前文件系统上实际的文本文件实现是不可能的。

文本文件是顺序的,因为文本文件中的行可以是任意长度。 删除特定行意味着从该点重写整个文件。

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

'line1\nline2reallybig\nline3\nlast line'

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

如果您知道文本文件中每一行的大小,可以使用.truncate(line_size * line_number)在任何位置截断文件,但即使这样,您也必须在该行之后重写所有内容。

答案 2 :(得分:6)

最好将索引保存到文件中,这样就可以从最后停止的位置开始,而不会破坏文件的一部分。像这样的东西会起作用:

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

答案 3 :(得分:4)

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

如果您的脚本打印出它打破的行号并将行号作为参数,那么您可以告诉它从哪个行开始处理?

答案 4 :(得分:4)

首先,调用操作truncate可能不是最佳选择。如果我正确理解了问题,您希望删除文件中当前位置的所有内容。 (我希望truncate能够删除从当前位置到文件末尾的所有内容。这就是标准Python truncate方法的工作方式,至少在我正确使用Google搜索时。)

其次,我不确定在使用for循环进行迭代时修改文件是明智的。保存处理的行数并在主循环结束后删除它们不是更好,异常与否?文件迭代器支持in-place filtering,这意味着之后删除已处理的行应该相当简单。

P.S。我不懂Python,带着一点点盐。

答案 5 :(得分:2)

相关帖子看起来是一个很好的策略,请参阅  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;

我不确定它是否适用于Windows。   在Mac上尝试过,它确实可以解决问题。

答案 6 :(得分:1)

这是我用于基于文件的队列。它返回第一行并用其余的重写文件。完成后,它返回None:

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