Эффективное добавление текста в очень большой текстовый файл на Python - PullRequest
2 голосов
/ 11 февраля 2011

Мне нужно добавить произвольный текст к существующему, но очень большому (от 2 до 10 ГБ) текстовому файлу.Из-за большого размера файла я стараюсь не читать файл весь в память.Но я слишком консервативен с построчными итерациями?Принесет ли переход на метод 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 ]

2 голосов
/ 03 апреля 2011

Если это в Windows NTFS, вы можете вставить в середину файла. (Или так мне сказали, я не разработчик Windows).

Если это в системе POSIX (Linux или Unix), вы должны использовать «cat», как сказал кто-то другой. cat очень эффективен, использует каждый трюк в книге, чтобы добиться оптимальной производительности (т. е. копирование пустот буферов и т. д.)

Однако, если вам нужно сделать это на python, код, который вы представили, можно улучшить, используя shutil.copyfileobj () (который принимает 2 дескриптора файла) и tempfile.TeoraryFile (создайте файл, который автоматически удаляется при закрытии):

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 голос
/ 11 февраля 2011

Вы можете использовать инструменты, более подходящие для работы os.system("cat file1 file2 > file3")

1 голос
/ 11 февраля 2011

Что вы хотите сделать, это прочитать файл большими (от 64 КБ до нескольких МБ) блоками и записать их.Другими словами, вместо отдельных строк используйте огромные блоки.Таким образом вы выполняете наименьшее количество операций ввода-вывода, и, надеюсь, ваш процесс будет связан с вводом-выводом, а не с процессором.

0 голосов
/ 11 февраля 2011

Если честно, я бы порекомендовал вам просто написать это на C, если вы беспокоитесь о времени выполнения.Выполнение системных вызовов из Python может быть довольно медленным, и поскольку вам придется выполнять lot из них, независимо от того, применяете ли вы построчное или необработанное чтение блоков, это действительно затягивает.

...