The zipfile write() method supports an extra argument (arcname) which is the archive name to be stored in the zip file, so you would only need to change your code with:
from os.path import basename
...
zip.write(first_path, basename(first_path))
zip.write(second_path, basename(second_path))
zip.close()
When you have some spare time reading the documentation for zipfile will be helpful.
Answer from João Pinto on Stack OverflowThe zipfile write() method supports an extra argument (arcname) which is the archive name to be stored in the zip file, so you would only need to change your code with:
from os.path import basename
...
zip.write(first_path, basename(first_path))
zip.write(second_path, basename(second_path))
zip.close()
When you have some spare time reading the documentation for zipfile will be helpful.
I use this function to zip a directory without include absolute path
import zipfile
import os
def zipDir(dirPath, zipPath):
zipf = zipfile.ZipFile(zipPath , mode='w')
lenDirPath = len(dirPath)
for root, _ , files in os.walk(dirPath):
for file in files:
filePath = os.path.join(root, file)
zipf.write(filePath , filePath[lenDirPath :] )
zipf.close()
#end zipDir
The easiest way is to use shutil.make_archive. It supports both zip and tar formats.
import shutil
shutil.make_archive(output_filename, 'zip', dir_name)
If you need to do something more complicated than zipping the whole directory (such as skipping certain files), then you'll need to dig into the zipfile module as others have suggested.
As others have pointed out, you should use zipfile. The documentation tells you what functions are available, but doesn't really explain how you can use them to zip an entire directory. I think it's easiest to explain with some example code:
import os
import zipfile
def zipdir(path, ziph):
# ziph is zipfile handle
for root, dirs, files in os.walk(path):
for file in files:
ziph.write(os.path.join(root, file),
os.path.relpath(os.path.join(root, file),
os.path.join(path, '..')))
with zipfile.ZipFile('Python.zip', 'w', zipfile.ZIP_DEFLATED) as zipf:
zipdir('tmp/', zipf)
As shown in: Python: Getting files into an archive without the directory?
The solution is:
'''
zip_file:
@src: Iterable object containing one or more element
@dst: filename (path/filename if needed)
@arcname: Iterable object containing the names we want to give to the elements in the archive (has to correspond to src)
'''
def zip_files(src, dst, arcname=None):
zip_ = zipfile.ZipFile(dst, 'w')
print src, dst
for i in range(len(src)):
if arcname is None:
zip_.write(src[i], os.path.basename(src[i]), compress_type = zipfile.ZIP_DEFLATED)
else:
zip_.write(src[i], arcname[i], compress_type = zipfile.ZIP_DEFLATED)
zip_.close()
import os
import zipfile
def zipdir(src, dst, zip_name):
"""
Function creates zip archive from src in dst location. The name of archive is zip_name.
:param src: Path to directory to be archived.
:param dst: Path where archived dir will be stored.
:param zip_name: The name of the archive.
:return: None
"""
### destination directory
os.chdir(dst)
### zipfile handler
ziph = zipfile.ZipFile(zip_name, 'w')
### writing content of src directory to the archive
for root, dirs, files in os.walk(src):
for file in files:
### In this case the structure of zip archive will be:
### C:\Users\BO\Desktop\20200307.zip\Audacity\<content of Audacity dir>
# ziph.write(os.path.join(root, file), arcname=os.path.join(root.replace(os.path.split(src)[0], ""), file))
### In this case the structure of zip archive will be:
### C:\Users\BO\Desktop\20200307.zip\<content of Audacity dir>
ziph.write(os.path.join(root, file), arcname=os.path.join(root.replace(src, ""), file))
ziph.close()
if __name__ == '__main__':
zipdir("C:/Users/BO/Documents/Audacity", "C:/Users/BO/Desktop", "20200307.zip")
The zipfile.write() method takes an optional arcname argument that specifies what the name of the file should be inside the zipfile
I think you need to do a modification for the destination, otherwise it will duplicate the directory. Use :arcname to avoid it. try like this:
Copyimport 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")
Copyzf.write(tofile)
to change
Copyzf.write(tofile, zipfile_dir)
for example
Copyzf.write("/root/files/result/root/files/result/new.txt", "/root/files/results/new.txt")