Python:写入大文件时,是保持文件打开还是根据需要打开并追加?

3 投票
1 回答
9166 浏览
提问于 2025-04-18 06:40

我在想,怎么在Python中更好地处理写入一个大文件的问题。

我的Python代码会循环很多次,运行一个外部程序(是个古老的Fortran程序,输入文件格式很奇怪),读取它的输出(一个只有一行的文件),做一些非常简单的处理,然后写入一个汇总的输出文件。这个外部程序执行得很快(通常不到1秒钟)。

import subprocess as sp

f_compiled_out = open("compiled.output", "w") 

for i in range(len(large_integer)):

  write_input_for_legacy_program = prepare_input()

  sp.call(["legacy.program"])

  with open("legacy.output", "r") as f:
    input = f.readline()

  output = process(input)

  f_compiled_out.write(output)


close(f_compiled_out)

我想到三种方法可以生成这个汇总的输出文件。

  1. 我现在正在做的方式。

  2. 在每次主循环中,用 open("comiled.output", "a") as f: f.write(output) 打开 f_compiled_out,并追加内容。

  3. 用awk来做简单的处理,然后用cat把输出追加到“compiled.output”的末尾。

那么,(1) 保持一个大文件打开并在末尾写入,和 (2) 每次写入时都打开并追加,和 (3) 用awk处理后再用cat来生成“compiled.output”,这三种方法的开销分别是什么呢?

在任何时候,整个输出都不需要在内存中。

附言:如果有人能看到其他可能导致在N_loops增大时变慢的明显问题,那就太好了!

1 个回答

5

打开和关闭文件确实是有代价的。不过,如果你的老旧程序响应需要一秒钟或更久,你可能不会太在意这个问题。

def func1():
    for x in range(1000):
        x = str(x)
        with open("test1.txt", "a") as k:
            k.write(x)

1 loops, best of 3: 2.47 s per loop

def func2():
    with open("test2.txt", "a") as k:
        for x in range(1000):
            x = str(x)
            k.write(x)

100 loops, best of 3: 6.66 ms per loop

不过,如果你的文件真的很大,处理起来就会变慢,比如超过800MB的文件。

def func3(file):
    for x in range(10):
        x = str(x)
        with open(file, "a") as k:
            k.write(x)

12KB的文件:

10 loops, best of 3: 33.4 ms per loop

超过800MB的文件:

1 loops, best of 3: 24.5 s per loop

保持文件打开主要会消耗内存。

我建议使用SQlite来存储你的数据。

撰写回答