вторник, 9 августа 2011 г.

Распаковываю большой файл. Python

Есть у меня коллекторы, где собираются и обрабатываются flow-потоки с оборудования. Их надо обрабатывать, считать кто сколько и куда байтов послал/получил.
С изменением сети, объемы растут и наступил такой момент, что мой старый скрипт отказался распаковывать 850 метровый архив с ошибкой "Memory Error".
Спасибо, что добрый человек (Гриша, привет!) подсказал как справиться с этим. Ну и спасибо, конечно stackowerflow.com
Итак код:

def read_by_pieces(file_object, piece_size = 1048576): ## 1Mb
    while True:
        data = file_object.read(piece_size)
        if not data:
            break
        yield data

if __name__ == '__main__':
    import gzip
    gz = gzip.open ('d:\\2011-08-07_04.txt.gz') # largefile ~ 850 Mb
    ungz = open ('d:\\2011-08-07_04.txt', 'wb')
    for piece in read_by_pieces(gz, 10485760): ## 10 Mb
        ungz.write(piece)


В результате, распаковывается 850 Mb файл в 3.5 Гб файл за примерно 5 минут.
Я думаю, можно добиться и лучших результатов, но мне сейчас нужно именно такое наколенное решение.

3 комментария:

  1. Посмотри еще на Posix API posix_fadvice (),

    Эта функция позволяет подсказать системе что ты будешь читать файл последовательно, и тогда она тебе его будет дополнительно кэшировать (readahead)

    еще можно посмотреть на readahead ().

    ОтветитьУдалить
  2. А в виндах доступен PosixAPI?

    ОтветитьУдалить
  3. Да.
    Можно поставить например cygwin или mingw.

    Но то, про что я писал скорее всего будет работать только под Unix системы.

    ОтветитьУдалить