Python Gzip — добавление к файлу на лету

Можно ли добавить текстовый файл gzip на лету с помощью Python?

В основном я делаю это: -

import gzip
content = "Lots of content here"
f = gzip.open('file.txt.gz', 'a', 9)
f.write(content)
f.close()

Строка добавляется (обратите внимание, «добавляется») к файлу каждые 6 секунд или около того, но результирующий файл имеет такой же размер, как и стандартный несжатый файл (примерно 1 МБ после завершения).

Явное указание уровня сжатия также не имеет значения.

Если после этого я заархивирую существующий несжатый файл, его размер уменьшится примерно до 80 КБ.

Я предполагаю, что невозможно «добавить» файл gzip на лету и сжать его?

Является ли это случаем записи в буфер String.IO, а затем сброса в файл gzip после завершения?


person general exception    schedule 07.08.2013    source источник
comment
Чтобы алгоритм gzip работал эффективно, он должен получить весь контент для сжатия. В противном случае вы просто добавляете куски сжатого содержимого, которые не имеют ничего общего друг с другом.   -  person Nadh    schedule 07.08.2013
comment
@Nadh, я думаю, моя последняя строка верна? Записать в String.IO и сбросить в gzip?   -  person general exception    schedule 07.08.2013
comment
Да, это должно сработать. Вам просто нужно убедиться, что весь контент сжат вместе в любой момент.   -  person Nadh    schedule 07.08.2013
comment
Я смутно припоминаю, что zlib можно использовать для выполнения потокового сжатия, т.е. не видя заранее все данные.   -  person Hans Then    schedule 07.08.2013
comment
Проблема заключается в добавлении только одной строки данных за раз. Чтобы gzip работал эффективно, ему требуется по крайней мере некоторое количество данных одновременно --- не обязательно весь файл, но определенно больше одной строки. Если отправлять сразу весь файл слишком сложно, вы также можете отправить его кусками по 16 КБ или что-то в этом роде.   -  person Armin Rigo    schedule 07.08.2013
comment
Предполагая, что это предварительная обработка данных, можете ли вы добавить эту строку прямо перед обработкой данных. То есть вместо open gzip -> запись -> close -> open gzip -> process, do open gzip -> read -> добавить одну строчку -> process   -  person Mai    schedule 07.08.2013
comment
обратите внимание, что ваш фрагмент не работает в python 3, если вы не добавите атрибут t (текстовый режим).   -  person Jean-François Fabre    schedule 12.10.2017


Ответы (1)


Это работает в смысле создания и поддержки действительного файла gzip, поскольку формат gzip позволяет объединять потоки gzip.

Однако это не работает в том смысле, что вы получаете паршивое сжатие, поскольку вы даете каждому экземпляру сжатия gzip так мало данных для работы. Сжатие зависит от использования истории предыдущих данных, но здесь gzip практически не используется.

Вы можете либо а) накопить по крайней мере несколько тысяч данных, много ваших строк, прежде чем вызвать gzip для добавления в файл еще одного потока gzip, либо б) сделать что-то гораздо более сложное, которое добавляется к одному потоку gzip, оставляя действительный gzip поток каждый раз и обеспечивает эффективное сжатие данных.

Вы найдете пример б) в C, в gzlog.h и gzlog.c. Я не верю, что Python имеет все интерфейсы к zlib, необходимые для реализации gzlog непосредственно в Python, но вы можете взаимодействовать с кодом C из Python.

person Mark Adler    schedule 07.08.2013