0

How can I add files and zip the folder?

So far, using zipfile, I’m able to create a zip.

Dan Me
  • 2,143
  • 4
  • 19
  • 19
  • It can help you; http://stackoverflow.com/questions/1855095/how-to-create-a-zip-archive-of-a-directory/ – alican akyol Mar 23 '17 at 21:19
  • 1
    Possible duplicate of [How to create a zip archive of a directory](http://stackoverflow.com/questions/1855095/how-to-create-a-zip-archive-of-a-directory) – vallentin Mar 23 '17 at 21:19

1 Answers1

1

How can I create a folder to add files and zip the folder?

You can do what you want by following these steps:

To create a folder, use os.mkdir like this:

import os
os.mkdir('spam') # your folder name

then you can write files to it or use shutil.copy to make copies of existent files.

# to write files:
with open('./spam/eggs.txt', 'w') as fp: # creates a text file in spam named eggs.txt
    fp.write('hello') # write hello

# to copy files
import shutil
shutil.copy('eggs.txt', './spam/eggs.txt') # copy eggs.txt from the current working dir to spam folder

then to zip the folder, you had the right idea, to use zipfile like this:

from zipfile import ZipFile, ZIP_DEFLATED

zipfp = ZipFile('spam.zip', 'w', ZIP_DEFLATED) # create a new zip file named spam.zip

for root, dirname, files in os.walk('./spam'): # walk in the spam folder
    [zipfp.write(os.path.join('./spam',file)) for file in files] # write them to the zip file
zipfp.close()

A complete example:

import os
from zipfile import ZipFile, ZIP_DEFLATED
os.mkdir('spam')
with open('./spam/eggs.txt', 'w') as fp: 
    fp.write('hello')
with ZipFile('spam.zip', 'w', ZIP_DEFLATED) as zipfp:
    for root, dirname, files in os.walk('./spam'): 
        [zipfp.write(os.path.join('./spam',file)) for file in files] 

The result of this code is it produces a compressed folder named spam.zip and in the zip file, there's a txt file named eggs.txt which contains the text 'hello'.

To clarify for the OP:

[zipfp.write(os.path.join('./spam',file)) for file in files]

is equivalent to:

for file in files:
     zipfp.write(os.path.join('./spam',file))

it's just simpler to write it using list comprehension.

Taku
  • 31,927
  • 11
  • 74
  • 85
  • Appreciate the response! A few things to clear up, are you pulling the files from the folder created, and adding them to the zip? What I was trying to achieve was create a new folder and add files to it, and create a new zip and add the folder to it. Also, why `ZIP_DEFLATED`? Thank you in advance! – Dan Me Mar 23 '17 at 22:36
  • ZIP_DEFLATED means to use the usual ZIP compression method. You can get rid of that line if you want – Taku Mar 23 '17 at 22:48
  • What I am doing is: 1st create a folder, 2nd add files to that folder either by copying or writing directly, 3rd create a new empty zipfile, 4th copy the folder to that zipfile – Taku Mar 23 '17 at 22:48
  • you can try it out if you want, and see the results yourself, just don't do the shutil.copy part since I don't believe you actually have a file called eggs.txt – Taku Mar 23 '17 at 22:53
  • What's the advantage of using the ZIP compression method? And with the code I provided, how would I integrate the newly created folder, and how can I add the files to it first? Would I do the following to add the folder to the zip: `spam = os.mkdir('spam')` `z = zipfile.ZipFile("testzip1", "a")` `z.write(spam)` And if so, how can I add the files to the folder first?` – Dan Me Mar 23 '17 at 22:54
  • by folder in the second to last word, do you mean a zip file or just a folder? – Taku Mar 23 '17 at 22:56
  • No, meant the 'spam' folder. Would like to add it to the zip file – Dan Me Mar 23 '17 at 22:56
  • See the last three lines of my answer (if it doesn't work before, it's because I forgot to close it) – Taku Mar 23 '17 at 22:58
  • Saw it. But what's the need to walk through the spam folder, file by file, if I just want to add the folder to the zip directly if possible. And could you clarify on: `for root, dirname, files` and `for file in files`. And lastly, when what's the upside to `ZIP_DEFLATED`? – Dan Me Mar 23 '17 at 23:00
  • The down side of using `zipfile` is that you can only add one file at a time...(no folders) – Taku Mar 23 '17 at 23:01
  • Well...the upside of ZIP_DEPLATED is that it's compressed, unlike the default which isn't compressed – Taku Mar 23 '17 at 23:03
  • Got it. How can I add existing files to the folder 'spam'? Wouldn't have to write any contents directly. Just need to add them to the 'spam' folder. – Dan Me Mar 23 '17 at 23:03
  • To make it clear(if you didn't understand me), you dont even need the spam folder, I made the folder because you stated in your question that *how can i create a folder to add files*. You can directly save to the zipfile by doing it using this format: `zipf.write("filename")` – Taku Mar 23 '17 at 23:06
  • To add existing files to the `spam` folder, see under `# to copy files` in my answer. replace `'eggs.txt'` with the file path to the existing file and the eggs.txt in `'./spam/eggs.txt'` to the desired name that you want to call it when it's copied into the spam folder – Taku Mar 23 '17 at 23:07
  • And previously you asked to clarify `for root, dirname, files in os.walk('./spam'):`. I only used this to iterate through the spam folder and add the files one by one to the zip file – Taku Mar 23 '17 at 23:11
  • Thank you so much! Makes sense. Will give it an attempt now. – Dan Me Mar 23 '17 at 23:19
  • Sorry but a few more questions. What's the reason for defining root, dirname, files? Does it iterate through each (root, then dirname, then files) of those data as well? And what does the `[ ]` mean in `[zipfp.write(os.path.join('./spam',file)) for file in files] ` – Dan Me Mar 23 '17 at 23:37
  • in my example ` root, dirname` are only place holders, while `files` is the one I actually need because it contain a list of all the files in the spam folder. – Taku Mar 23 '17 at 23:39
  • the brackets are called list comprehension, Ill show what it means in a edit of my answer – Taku Mar 23 '17 at 23:40
  • Got it! As for the place holders, they have to be provided, correct? – Dan Me Mar 23 '17 at 23:46
  • yes indeed, since `os.walk('./spam')` returns three arguments not one. but you can call them what every you want, but many people prefer to either name it by what they return, or called the unwanted return argument `_`. so some people does this instead: `for _, _, files in os.walk('./spam')` since the underscore is usually referred to a disposable variable – Taku Mar 23 '17 at 23:51