在Python中高效地在大型文本文件前添加文本

2 投票
4 回答
3506 浏览
提问于 2025-04-16 11:37

我需要在一个已经存在的、但非常大的文本文件前面加上一些任意的文字。这个文件的大小在2到10GB之间,所以我想避免一次性把整个文件读到内存里。但是,我这样逐行读取是不是太小心了?如果我改用readlines(sizehint)的方法,能不能在性能上比我现在的做法有很大提升?

最后的删除和移动操作并不是最理想的,但据我所知,处理这种线性数据的操作不能就地进行。不过我对Python不太熟悉,也许Python里有一些特别的功能可以让我更好地完成这个任务?

import os
import shutil
def prependToFile(f, text):
    f_temp = generateTempFileName(f)
    inFile  = open(f, 'r')
    outFile = open(f_temp, 'w')    
    outFile.write('# START\n')
    outFile.write('%s\n' % str(text))
    outFile.write('# END\n\n')
    for line in inFile:
        outFile.write(line)
    inFile.close()
    outFile.close()
    os.remove(f)
    shutil.move(f_temp, f)

4 个回答

1

你可以使用更合适的工具来完成这个任务,比如用这条命令 os.system("cat file1 file2 > file3")

2

如果你是在Windows的NTFS文件系统上,你可以在文件中间插入内容。(我听说的,毕竟我不是Windows开发者)。

如果你是在POSIX系统(比如Linux或Unix)上,正如其他人提到的,你应该使用“cat”命令。cat非常高效,利用了各种技巧来获得最佳性能(比如避免复制缓冲区等等)。

不过,如果你非要用Python来做,你可以改进你提供的代码,使用shutil.copyfileobj()(这个函数需要两个文件句柄)和tempfile.TemporaryFile(这个函数会创建一个在关闭时自动删除的文件):

import os
import shutil
import tempfile

def prependToFile(f, text):
    outFile = tempfile.NamedTemporaryFile(dir='.', delete=False)
    outFile.write('# START\n')
    outFile.write('%s\n' % str(text))
    outFile.write('# END\n\n')
    shutil.copyfileobj(file(f, 'r'), outFile)
    os.remove(f)
    shutil.move(outFile.name, f)
    outFile.close()

我觉得os.remove(f)这个部分是不必要的,因为shutil.move()会删除f。不过,你最好测试一下。此外,“delete=False”可能也不是必须的,但保留它可能更安全。

1

你想要做的是把文件分成大块(可以是64KB到几MB不等)来读取,然后再把这些大块写出去。换句话说,不要一行一行地处理,而是用很大的块来处理。这样做可以减少输入输出的次数,希望你的程序主要受输入输出的速度限制,而不是处理器的速度限制。

撰写回答