Эффективное добавление текста в очень большой текстовый файл на языке Python
Я должен добавить некоторый произвольный текст к существующему, но очень большому (диапазон 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('# STARTn')
outFile.write('%sn' % str(text))
outFile.write('# ENDnn')
for line in inFile:
outFile.write(line)
inFile.close()
outFile.close()
os.remove(f)
shutil.move(f_temp, f)
4 ответа:
То, что вы хотите сделать, это прочитать файл в больших (от 64k до нескольких MB) блоках и записать блоки. Другими словами, вместо отдельных линий используйте огромные блоки. Таким образом, Вы делаете как можно меньше операций ввода-вывода, и, надеюсь, ваш процесс связан с вводом-выводом, а не с ЦП.
Если это на Windows NTFS, вы можете вставить в середину файла. (Или так мне сказали, я не разработчик Windows).
Если это на системе POSIX (Linux или Unix), вы должны использовать "cat", как сказал кто-то другой. кот порочно эффективен, используя каждый трюк в книге, чтобы получить оптимальную производительность (т. е. пустоты, копирующие буферы и т.д.)
Однако, если вы должны сделать это в python, представленный вами код может быть улучшен с помощью shutil.copyfileobj () (который принимает 2 дескриптора файлов) и темпфайл.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()
Я думаю, что ОС.удалить(f) не нужно, так как шутил.move() удалит f. однако вы должны проверить это. Кроме того," delete=False " может быть не нужен, Но может быть безопасно оставить его.
Вы можете использовать инструменты, лучше подходящие для работы
os.system("cat file1 file2 > file3")
Честно говоря, я бы рекомендовал вам просто написать это в C, если вы беспокоитесь о времени выполнения. Выполнение системных вызовов из Python может быть довольно медленным, и так как вам придется выполнять Много из них, независимо от того, выполняете ли вы подход построчного или необработанного чтения блоков, это действительно затянет все вниз.