Python: Créer un streaming gzip avais de fichiers?
Je suis à essayer de comprendre la meilleure façon de compresser un flux de données avec Python zlib
.
J'ai un fichier-comme les flux d'entrée (input
, ci-dessous) et une sortie de la fonction qui accepte un fichier de type (output_function
, ci-dessous):
with open("file") as input:
output_function(input)
Et j'aimerais gzip compresse input
morceaux avant de les envoyer à output_function
:
with open("file") as input:
output_function(gzip_stream(input))
Il ressemble à la gzip module suppose que l'entrée ou la sortie sera un gzip avais fichier sur le disque... Donc je suppose que le zlib module est ce que je veux.
Cependant, il n'est pas nativement offre un moyen simple de créer un fichier de flux-like... Et le flux de compression, il n'soutien vient de la façon d'ajouter manuellement des données à une compression de la mémoire tampon, puis rinçage de la mémoire tampon.
Bien sûr, je pourrais écrire un wrapper autour de zlib.Compress.compress
et zlib.Compress.flush
(Compress
est retourné par zlib.compressobj()
), mais je serais inquiet au sujet d'obtenir des tailles de mémoire tampon de mal, ou quelque chose de similaire.
Alors, quelle est la façon la plus simple de créer un streaming, gzip compression de fichiers avec Python?
Modifier: Pour clarifier, les flux d'entrée et de la compression de flux de sortie sont à la fois trop grand pour tenir dans la mémoire, donc quelque chose comme output_function(StringIO(zlib.compress(input.read())))
n'a pas vraiment résoudre le problème.
- J'ai trouvé une mise en œuvre de l ' autre chose - un fichier comme décompresser un gzip avais flux à effbot: effbot.org/librarybook/zlib.htm ... Mais je suis à la recherche pour le contraire (bien que je suppose qu'il pourrait être utile si j'ai besoin d'écrire mon propre)
Vous devez vous connecter pour publier un commentaire.
C'est assez encombrants (auto-référencement, etc; il suffit de mettre quelques minutes à l'écrire, rien de vraiment élégant), mais il fait ce que vous voulez si vous êtes toujours intéressé à l'aide de
gzip
au lieu dezlib
directement.Fondamentalement,
GzipWrap
est un (très limitée) fichier-comme l'objet qui produit un fichier au format gzip des itérable (par exemple, un fichier-comme l'objet, d'une liste de chaînes, un générateur...)Bien sûr, il produit binaire, donc il n'y a pas de sens dans la mise en œuvre "readline".
Vous devriez être en mesure de développer pour couvrir d'autres cas, ou pour être utilisé comme un objet iterable objet lui-même.
self
à la GzipFile. Je l'aime!Ici est un nettoyant non auto-référencement version basée sur Ricardo Cárdenes " très utile de répondre.
Avantages:
ret = b''.join(ret_list)
au lieu de cela, et si votre flux d'entrée est une chaîne, alors vous devez coder par exempleself.__gzip.write(s.encode('utf-8')
Le gzip module prend en charge la compression d'un fichier-comme l'objet, passer une fileobj paramètre GzipFile, ainsi qu'un nom de fichier. Le nom de fichier que vous transmettez n'a pas besoin d'exister, mais l'en-tête gzip a un nom de domaine qui doit être rempli.
Mise à jour
Cette réponse ne fonctionne pas. Exemple:
de sortie:
fileobj
doit être un gzip avais flux d'entrée ou une sortie de flux qui le gzip avais données seront écrites. Donc, c'est mieux que rien, mais pas encore tout à fait ce que je voudrais.fd=gzip.GzipFile(fileobj=fd)
et il fonctionne comme il le devrait.fd
l'objet n'a passeek
méthode.Utiliser le cStringIO (ou StringIO) module en conjonction avec zlib:
zlib.compress
) et doit ensuite être chargé dans la mémoire nouveau quand il est retourné à partir dezlib.decompress
.zlib.compressobj()
etzlib.decompressobj()
? Parfait pour la segmentation.Cela fonctionne (au moins en python 3):
Ici, il écrit à s3fs de fichier de l'objet avec une compression gzip sur elle.
La magie est la
f
paramètre, qui est GzipFile defileobj
. Vous devez donner un nom de fichier gzip-tête.