7

I am new to python. My requirement is to zip (with compression) all files from a source directory to a target directory. I have used following code from stackOverFlow.

import zipfile, os
locfile = "D:\Python\Dir_dir\Dir_dir\ABC.txt"
loczip = "D:\Python\Dir_dir\Dir_dir2\ABC_TEST.zip"
zip = zipfile.ZipFile (loczip, "w")
zip.write (locfile)
zip.close()

It is creating a zip file but it contains the entire inherited directory structure. Except the drive(D:/) the rest of the structure is added to zip. It looks like the following: "D:\Python\Dir_dir\Dir_dir2\ABC_TEST.zip\Python\Dir_dir\Dir_dir\ABC.txt"

whereas i wanted: "D:\Python\Dir_dir\Dir_dir2\ABC_TEST.zip\ABC.txt"

Also it is not compressed.

3
  • 1
    Your code does not create a zip file that "contains the entire inherited directory structure". It has one file in with a path of Python\Dir_dir\Dir_dir which is correct (see screenshot) since archive file names should be relative to the archive root, so shouldn't start with path separator (or drive letter). This is in the documentation, so I suggest you augment your reading of stackOverFlow code with looking at that.
    – martineau
    Commented Aug 22, 2014 at 15:59
  • 2
    As an aside, use raw strings or double-escape backslashes in Windows path names (add an r to the front like r"D:\Python\Dir_dir\Dir_dir2\ABC_TEST.zip"). Otherwise, Python will convert sequences like '\t' and '\n' to tabs and new lines.
    – tdelaney
    Commented Aug 22, 2014 at 16:06
  • Or just use forward slashes, easy to do, easy to read. Commented Oct 20, 2017 at 20:44

2 Answers 2

11

To enable compression, specify compression method in the constructor:

zip = zipfile.ZipFile(loczip, "w", zipfile.ZIP_DEFLATED)

I think you are asking to remove the relative paths of files inside the zip file. If you really want that, you could write:

zip.write(locfile, os.path.basename(locfile))

However this is probably a bad idea, since removing all path information would result in a naming conflict if you zip up two files with the same name.

5
  • Completely removing the directory structure of the file added to the archive is not what the OP wants. You might also mention how you've arranged for the data to be compressed.
    – martineau
    Commented Aug 22, 2014 at 16:17
  • 1
    @martineau - explained compression as you suggested Commented Aug 22, 2014 at 16:31
  • os.path.basename(locfile) sets the file name in the archive to just 'ABC.txt' with all path information stripped. That might be OK for first level files in the source directory, but there are some in any subfolders, it likely be a problem.
    – martineau
    Commented Aug 22, 2014 at 17:08
  • We're interpreting "i wanted: "D:\Python\Dir_dir\Dir_dir2\ABC_TEST.zip\ABC.txt" differently. Did you look at the screenshot I made of what's produced?
    – martineau
    Commented Aug 22, 2014 at 17:12
  • @martineau - I have reworded my answer to make my interpretation of the question clearer, and to make sure the OP understands why it could be a problem. Commented Aug 22, 2014 at 17:51
2

Check the official documentation and it addresses your issues clearly.

ZipFile.write(filename, arcname=None, compress_type=None)

compress should be one of the defined constants, e.g., ZIP_DEFLATED

Note that you can also specifcy the conmpression type on the constructor and it will apply to all files added to the zip archive.

The documentation also includes this note: Archive names should be relative to the archive root, that is, they should not start with a path separator.

Also if you had simply entered python zipfile into any search engine, you would have seen the official documentation as one of the first links.

Not the answer you're looking for? Browse other questions tagged or ask your own question.