1

I have a directory dir which contains 3 files: f1.txt, f2.txt, f3.pngt.

I want to create a zip archive given the path of that directory where each file will be a zip archive. The resulting zipped_archive.zip should be on the same path as the dir is.

That is, I want the zipped_archive.zip to contain f1.zip, f2.zip, f3.zip where each of these f#.zip files contains the correspondingly-named txt or png file.

The above is better illustrated with this file-structure:

tmp
 |
 +-- dir
 |    |
 |    +-- f1.txt
 |    +-- f2.txt
 |    +-- f3.txt
 |
 +-- zipped_archive.zip
 |          |
 |          +-- f1.zip
 |          |     |
 |          |     +-- f1.txt
 |          +-- f2.zip
 |          |     |
 |          |     +-- f2.txt
 |          +-- f3.zip
 |          |     |
 |          |     +-- f3.png

I have tried to apply zipfile as seen in this answer and shutil as seen this answer, both from the same question. I though of using shutil.make_archive on each file and in the end do a ziph.write with that result but I struggle to make it work and got confused.

Can someone suggest/provide some example code to help me understand how this works?

Community
  • 1
  • 1
  • 1
    If you provide the code you've already tried, it'll be much easier to examine the problem. – Sangbok Lee Mar 03 '17 at 17:12
  • @SangbokLee True but I chose not too because I merely tried to combine the code from the 2 answers I mentioned exactly as I described and the behaviour/results is not helpful (I think). –  Mar 03 '17 at 17:14
  • @nk-fford It's still good practice to provide the code you've tried, along with a specific description of how it's behaving differently than you expect (including full stack trace if you're getting an Exception). Otherwise you're just asking for code, and that's not really what StackOverflow is for. – glibdud Mar 03 '17 at 17:23
  • @glibdud You are right. I will try to add my rough code attempts. –  Mar 03 '17 at 21:48

1 Answers1

0

Try this.

import os
import zipfile

target = "dir"
os.chdir(target)  # change directory to target
files = os.listdir('.')  # get all filenames into a list

zipfiles = []  # a list which will be used later for containing zip files
for i in range(len(files)):
    fn = files[i].split('.')[0] + '.zip'  # f#.??? -> f#.zip
    zipf = zipfile.ZipFile(fn, 'w', zipfile.ZIP_DEFLATED)
    zipf.write(files[i])
    zipf.close()
    zipfiles.append(fn)  # put f#.zip into the list for later use

zipf = zipfile.ZipFile('../zipped_archive.zip', 'w', zipfile.ZIP_DEFLATED)
for i in range(len(zipfiles)):
    zipf.write(zipfiles[i])
    os.remove(zipfiles[i])  # delete f#.zip after archiving

zipf.close()
os.chdir('..')  # change directory to target's parent
Sangbok Lee
  • 1,846
  • 2
  • 12
  • 29
  • Works great, thanks! Could you please add a short description (or comments) so that I can easier follow and understand your solution? –  Mar 04 '17 at 08:42
  • Okay I added some comments. If you still have difficulty in understanding, try running one line at one time and print its result in Python console. – Sangbok Lee Mar 04 '17 at 09:55
  • Confused about your 10th line: why do you rename/add the `.zip` suffix at the end of each file? Should it not the next `ZipFile` command which does the compression actually add that suffix? –  Mar 06 '17 at 09:52
  • As far as I know, `zipfile` does not add an extension(`.zip`) automatically. As you can see in [the documentation](https://docs.python.org/3.6/library/zipfile.html#zipfile-objects), you should provide a full filename. – Sangbok Lee Mar 06 '17 at 10:39