Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create .zip in Python?

I'm trying to create a function in my script that zips the contents of a given source directory (src) to a zip file (dst). For example, zip('/path/to/dir', '/path/to/file.zip'), where /path/to/dir is a directory, and /path/to/file.zip doesn't exist yet. I do not want to zip the directory itself, this makes all the difference in my case. I want to zip the files (and subdirs) in the directory. This is what I'm trying:

def zip(src, dst):     zf = zipfile.ZipFile("%s.zip" % (dst), "w")     for dirname, subdirs, files in os.walk(src):         zf.write(dirname)         for filename in files:             zf.write(os.path.join(dirname, filename))     zf.close() 

This creates a zip that is essentially /. For example, if I zipped /path/to/dir, extracting the zip creates a directory with "path" in it, with "to" in that directory, etc.

Does anyone have a function that doesn't cause this problem?

I can't stress this enough, it needs to zip the files in the directory, not the directoy itself.

like image 431
tkbx Avatar asked Jan 28 '13 18:01

tkbx


People also ask

How do I create a ZIP file in Python?

Create a zip archive from multiple files in PythonCreate a ZipFile object by passing the new file name and mode as 'w' (write mode). It will create a new zip file and open it within ZipFile object. Call write() function on ZipFile object to add the files in it. call close() on ZipFile object to Close the zip file.

How do I zip two files in Python?

To zip multiple files in Python, use the zipfile. ZipFile() method. Iterate all the files that need to be zipped and use the write() method to write the final zipped file.

How can I create a ZIP file?

Right-click on the file or folder.Select “Compressed (zipped) folder”. To place multiple files into a zip folder, select all of the files while hitting the Ctrl button. Then, right-click on one of the files, move your cursor over the “Send to” option and select “Compressed (zipped) folder”.


1 Answers

The zipfile.write() method takes an optional arcname argument that specifies what the name of the file should be inside the zipfile.

You can use this to strip off the path to src at the beginning. Here I use os.path.abspath() to make sure that both src and the filename returned by os.walk() have a common prefix.

#!/usr/bin/env python2.7  import os import zipfile  def zip(src, dst):     zf = zipfile.ZipFile("%s.zip" % (dst), "w", zipfile.ZIP_DEFLATED)     abs_src = os.path.abspath(src)     for dirname, subdirs, files in os.walk(src):         for filename in files:             absname = os.path.abspath(os.path.join(dirname, filename))             arcname = absname[len(abs_src) + 1:]             print 'zipping %s as %s' % (os.path.join(dirname, filename),                                         arcname)             zf.write(absname, arcname)     zf.close()  zip("src", "dst") 

With a directory structure like this:

src └── a     ├── b     │   └── bar     └── foo 

The script prints:

zipping src/a/foo as a/foo zipping src/a/b/bar as a/b/bar 

And the contents of the resulting zip file are:

Archive:  dst.zip   Length     Date   Time    Name  --------    ----   ----    ----         0  01-28-13 11:36   a/foo         0  01-28-13 11:36   a/b/bar  --------                   -------         0                   2 files 
like image 82
andrewdotn Avatar answered Oct 01 '22 04:10

andrewdotn