How to compress a folder with everything inside using python zipfile?

Asked

Viewed 2,519 times

2

I am wanting to compress a file and a folder that has multiple files inside in a single file. zip using Python. The script is next p:

from zipfile import ZipFile,ZIP_DEFLATED

def zipar(lista):
    with ZipFile('teste.zip','w',ZIP_DEFLATED) as z:
        for i in lista:
            z.write(i)

zipar(['registro.py','Tudo'])

When I run the script, it compresses "register.py" and "All" folder, but the files that are inside the original "All" folder are not compressed together, that is, the folder is compressed empty. How do I fix this?

2 answers

3

Use the module shutil which is much more practical.

Example:

...
├─── minha_pasta/
│    ├── tudo/
│    │   ├── sub_pasta_1/
│    │   │   ├── arquivo_1
│    │   │   └── arquivo_2
│    │   ├── sub_pasta_2/
│    │   │   ├── arquivo_3
│    │   │   └── arquivo_4
│    │   └── sub_pasta_3/
│    │       ├── arquivo_5
│    │       └── arquivo_6
│    └── registro.py
└─── script.py

script py.:

#!/usr/bin/env python
from shutil import make_archive

make_archive('pasta_compactada', 'zip', 'minha_pasta')

Upshot:

pasta_compactada.zip/
├── tudo/
│   ├── sub_pasta_1/
│   │   ├── arquivo_1
│   │   └── arquivo_2
│   ├── sub_pasta_2/
│   │   ├── arquivo_3
│   │   └── arquivo_4
│   └── sub_pasta_3/
│       ├── arquivo_5
│       └── arquivo_6
└── registro.py

For details of the check function to documentation

If your directory structure is not the way you want it to be, just adjust it with commands like shutil.copy2.

  • There is a problem with this solution, how do you put several trustees/directories inside the same zip? in this case the ['registro.py','Tudo']?

  • 1

    It compresses everything inside /path/da/pasta copying the structure of directories and files within zipfile_name.zip. Test here on my computer before posting the answer and it’s all right. Tested there?

  • Yeah, but how do you put the file registro.py into that zip? As asked in the question you should put all files/directories that are in the entry list in it ficheiro.zip, in this case the file registro.py, and the directory Tudo (and all its contents)

  • This command copies the directory structure. Just adjust the directory as you want and compress. I don’t understand the mystery

  • But in the case of this problem the file registo.py is not inside that directory, but is supposed to put it in the same destination zip

  • I edited the answer. What I meant is that it can copy the files and folder that it wants to a temporary folder, compress and delete the temporary folder. Maybe it doesn’t even need the temporary folder, it depends on how it is working with this structure.

  • Yes, this gives but implies changing the original folder/file structure, however it gives yes

  • Anyway, I just wanted to supplement your answer, which I think is the right one to ask. However, someone will fall for this question in a google search, and I found it interesting to provide a different answer that can apply better to other situations. Thanks for the feedback, it sure improved the quality of the response. :)

  • You are welcome, yes your answer is appropriate when we want a directory and all its contents, it is also not wrong

Show 4 more comments

2


The problem is that you need to recursively specify the directories/files within the directory Tudo and others you may want, you get this via os.walk(), and because of the fact that registro.py not being in the same directory (Tudo) implies that you have to use zipfile:

import zipfile as zipf
import os

def zipar(arqs):
    with zipf.ZipFile('teste.zip','w', zipf.ZIP_DEFLATED) as z:
        for arq in arqs:
            if(os.path.isfile(arq)): # se for ficheiro
                z.write(arq)
            else: # se for diretorio
                for root, dirs, files in os.walk(arq):
                    for f in files:
                        z.write(os.path.join(root, f))

zipar(['registro.py','Tudo'])

Browser other questions tagged

You are not signed in. Login or sign up in order to post.