Python code to recursively create a zip file within a zip file for 'n' iterations


Python code to recursively create a zip file within a zip file for 'n' iterations



I'm trying (and failing) to create a Python function that essentially zips up some text, then zips the archive up again and again (the number based on a parameter).



So we'd end up with file1.zip containing file2.zip which in turn contains file3.zip. i.e (file1.zip(file2.zip(file3.zip))). Hope that's articulated well enough.


import io
import zipfile
import gzip

hexdata = "5a69702054657374"


def zip_it(filename, depth):
zip_buffer = io.BytesIO()

for i in range(0, depth):
with zipfile.ZipFile(zip_buffer, "a", zipfile.ZIP_DEFLATED, False) as zip_file:
zip_file.writestr(filename + str(i), bytes.fromhex(hexdata).decode("utf-8"))

with open(filename + ".zip", "wb") as f:
f.write(zip_buffer.getvalue())


if __name__ == '__main__':
zip_it("testfile", 3)



The above code is what I have so far, it's not quite right, it creates 1 compressed file with the 3files all at the same level and not within each other. I figure this is a recursive problem.



Also i'd probably want to do the same with gzip, rar etc - just saying in case if effects any help i get.



Thanks




1 Answer
1



I think you're right that this is a recursive task.



For this I'd separate the code for creating a zip file with data from the code which only writes a zipfile of a (-nother zip-) file.
Furthermore, the code for actually writing a real file to disk, not only BytesIO-objects, should be even outside of the function, because as a recursive function it is completely part of the loop.


import io
import zipfile

hexdata = "5a69702054657374"


def zip_it(filename, depth):

zip_buffer = io.BytesIO()

with zipfile.ZipFile(zip_buffer, "a", zipfile.ZIP_DEFLATED, False) as zip_file:
if depth > 0:
content = zip_it(filename, depth - 1)
fname = 'testZipFile'
depth = str(depth)
ext = '.zip'
else:
content = bytes.fromhex(hexdata).decode("utf-8")
fname = 'myTextfile'
depth = ''
ext = '.txt'
zip_file.writestr(fname + depth + ext, content)

return zip_buffer.getvalue()


if __name__ == '__main__':
with open("testfile" + ".zip", "wb") as f:
f.write(zip_it("testfile", 3))



Of course you could put this in another function, e.g. write_zip(filename) which calls zip_it, but this is a matter of taste or structure of your project.


write_zip(filename)


zip_it





Should of mentioned, that I want to do this all in memory with one write to disk
– molko
Jun 29 at 7:22





Yes, as your attempt already did. And so does my code.
– SpghttCd
Jun 29 at 7:24





Yes, that did the trick - much appreciated. To keep consistency with with the inner .zip files I added 'zip_file.writestr(filename + str(depth) + ".zip", content)'. Now i need make sure the first file (the actual text i'm compressing) does not have a .zip extension. Thanks again
– molko
Jun 29 at 9:37






you're welcome, see edit
– SpghttCd
Jun 29 at 9:57






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Comments

Popular posts from this blog

paramiko-expect timeout is happening after executing the command

Opening a url is failing in Swift

Export result set on Dbeaver to CSV