2016-11-17 1 views
0

Donc, j'essaie de compresser 3 fichiers texte de 10 Mo chacun dans un fichier comme tar.gz, mais cela ne semble pas réduire le tar.gz final. La taille finale du fichier tar.gz est toujours de 30 Mo.pourquoi python tarfile gz ne réduit pas la taille du fichier

Quelqu'un peut-il s'il vous plaît dites-moi pourquoi cela se passe-t-il? J'ai le plus haut niveau de compression

>>> import os 
>>> import sys 
>>> import tarfile 
>>> import tempfile 
tarmode="w:gz"): 
    ''>>> size_in_mb = 10 
>>> 
>>> def compress_str_to_tar(tmppath, files_str, tarfileprefix, tarmode="w:gz"): 
...  ''' compress string contents in files and tar. finally creates a tar file in tmppath 
...  @param tmppath: (str) pathdirectory where temp files to be compressed will be created 
...  @param files_str: (dict) {filename: filecontent_in_str} these will be compressed 
...  @param tarfileprefix: (str) output filename (without suffix) of tar 
...  @param tarmode: (str) w:gz or w:bz2 
...  ''' 
...  tar = tarfile.open(os.path.join(tmppath, tarfileprefix+'.tar.'+tarmode.split(':')[1]), tarmode, compresslevel=9) 
...  for filename in files_str: 
...   with open(os.path.join(tmppath, filename), 'wb') as tmpf: 
...    tmpf.write(files_str[filename]) 
...   tar.add(os.path.join(tmppath, filename), arcname=filename) 
...  tar.close() 
... 
... 
>>> mail_size = 0 
>>> files_str = {} 
>>> for i in range(3): 
...  d = os.urandom(1*size_in_mb*(10**6)) 
...  files_str['attachment'+str(i)+'.txt'] = d 
...  mail_size += sys.getsizeof(d) 
... 
... 
/10**6) 

tmppath = tempfile.mkdtemp() 
print('tar-tmppath', tmppath) 
tarfileprefix = 'tmpfoobar' 
compress_str_to_tar(tmppath, files_str, tarfileprefix, 'w:gz') 
print('mail_size', float(sys.getsizeof(open(os.path.join(tmppath, tarfileprefix+'.tar.gz')).read()))/10**6) 


>>> print('mail_size', float(mail_size)/10**6) 
('mail_size', 30.000111) 
>>> 
>>> tmppath = tempfile.mkdtemp() 
>>> print('tar-tmppath', tmppath) 
('tar-tmppath', '/tmp/tmpndifyt') 
>>> tarfileprefix = 'tmpfoobar' 
>>> compress_str_to_tar(tmppath, files_str, tarfileprefix, 'w:gz') 
>>> print('mail_size', float(sys.getsizeof(open(os.path.join(tmppath, tarfileprefix+'.tar.gz')).read()))/10**6) 
('mail_size', 30.009782) 
>>> 
>>> 
>>> 
+0

a besoin de reformatage. –

+1

Tout ne peut pas être compressé, ou il serait possible de compresser n'importe quoi à une très petite taille juste en compressant encore et encore. Quel genre de fichiers compressez-vous? Que se passe-t-il si vous faites un '.tar.gz' avec une méthode différente? –

+0

je serais d'accord que tout ne compresse pas, mais il a dit _text_ fichiers. Je ne m'attendrais pas à ce que les fichiers binaires aient un bon taux de compression, mais le texte devrait faire mieux que la compression _no_. –

Répondre

5

vous essayez de compresser des données générées par os.urandom qui est aléatoire.

Les données aléatoires se compriment très mal si la fonction aléatoire est bonne.

Le principe de compression consiste à identifier des motifs répétitifs. Le meilleur algorithme aléatoire est le moins répétitif des motifs que vous trouverez.

Je recommande que vous essayez avec vrais fichiers, ou un texte aléatoire généré à partir d'une liste donnée de mots (lettres non aléatoires) et vous aurez une meilleure compression.

0

Ainsi, comme @Jean dit, j'ai pu compresser 3 fichiers de 10 Mo avec la même caractère répété à 0.02MB =>d = ('1'*size_in_mb*10**6)

import os 
import sys 
import tarfile 
import tempfile 
size_in_mb = 10 

def compress_str_to_tar(tmppath, files_str, tarfileprefix, tarmode="w:gz"): 
    ''' compress string contents in files and tar. finally creates a tar file in tmppath 
    @param tmppath: (str) pathdirectory where temp files to be compressed will be created 
    @param files_str: (dict) {filename: filecontent_in_str} these will be compressed 
    @param tarfileprefix: (str) output filename (without suffix) of tar 
    @param tarmode: (str) w:gz or w:bz2 
    ''' 
    tar = tarfile.open(os.path.join(tmppath, tarfileprefix+'.tar.'+tarmode.split(':')[1]), tarmode, compresslevel=9) 
    for filename in files_str: 
     with open(os.path.join(tmppath, filename), 'wb') as tmpf: 
      tmpf.write(files_str[filename]) 
     tar.add(os.path.join(tmppath, filename), arcname=filename) 
    tar.close() 


mail_size = 0 
files_str = {} 
for i in range(3): 
    d = ('1'*size_in_mb*10**6) 
    files_str['attachment'+str(i)+'.txt'] = d 
    mail_size += sys.getsizeof(d) 


print('mail_size', float(mail_size)/10**6) 

tmppath = tempfile.mkdtemp() 
print('tar-tmppath', tmppath) 
tarfileprefix = 'tmpfoobar' 
compress_str_to_tar(tmppath, files_str, tarfileprefix, 'w:gz') 
print('mail_size', float(sys.getsizeof(open(os.path.join(tmppath, tarfileprefix+'.tar.gz')).read()))/10**6) 
il_size',>>> print('mail_size', float(mail_size)/10**6) 
('mail_size', 30.000111) 
>>> 
>>> tmppath = tempfile.mkdtemp() 
>>> print('tar-tmppath', tmppath) 
('tar-tmppath', '/tmp/tmpA3r51N') 
>>> tarfileprefix = 'tmpfoobar' 
>>> compress_str_to_tar(tmppath, files_str, tarfileprefix, 'w:gz') 
ize', float(sys.getsizeof(open(os.path.join(tmppath, tarfileprefix+'.tar.gz')).read()))/10**6) 


>>> print('mail_size', float(sys.getsizeof(open(os.path.join(tmppath, tarfileprefix+'.tar.gz')).read()))/10**6) 
('mail_size', 0.02958) 
>>> 
>>> 
>>> 
Code