Zip file and avoid directory structure

I have a Python script that has a new.txt file ( new.txt ).

 tofile = "/root/files/result/"+file targetzipfile = new.zip # This is how I want my zip to look like zf = zipfile.ZipFile(targetzipfile, mode='w') try: #adding to archive zf.write(tofile) finally: zf.close() 

When I do this, I get a zip file. But when I try to unzip the file, I get a text file inside a series of directories corresponding to the file path, i.e. I see a folder called root in the result directory and more directories in it, i.e.

/root/files/result/new.zip

and when I unpack new.zip I have a directory structure that looks like

 /root/files/result/root/files/result/new.txt. 

Is there a way that I can archive so that when I unpack, I get only new.txt .

In other words, I have /root/files/result/new.zip and when I unpack new.zip it should look like this

 /root/files/results/new.txt 
+10
source share
5 answers

The zipfile.write() method takes an optional arcname argument, which indicates that the file name should be inside the zipfile

I think you need to make changes to the destination, otherwise it will duplicate the directory. Use: arcname to avoid this. try like this:

 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") 
+20
source

Check out the documentation for Zipfile.write .

ZipFile.write (filename [, arcname [, compress_type]]) Write the named filename to the archive, assigning it the archive name arcname (by default, this will be the same as the file name, but without the drive letter and the leading delimiters removed ways)

https://docs.python.org/2/library/zipfile.html#zipfile.ZipFile.write

Try the following:

 import zipfile import os filename = 'foo.txt' # Using os.path.join is better than using '/' it is OS agnostic path = os.path.join(os.path.sep, 'tmp', 'bar', 'baz', filename) zip_filename = os.path.splitext(filename)[0] + '.zip' zip_path = os.path.join(os.path.dirname(path), zip_filename) # If you need exception handling wrap this in a try/except block with zipfile.ZipFile(zip_path, 'w') as zf: zf.write(path, zip_filename) 

The bottom line is that if you do not specify the name of the archive, the file name will be used as the name of the archive and will contain the full path to the file.

+4
source
 zf.write(tofile) 

change

 zf.write(tofile, zipfile_dir) 

eg

 zf.write("/root/files/result/root/files/result/new.txt", "/root/files/results/new.txt") 
+4
source

To illustrate most clearly,

Directory structure

:

 /Users └── /user . β”œβ”€β”€ /pixmaps . β”‚ β”œβ”€β”€ pixmap_00.raw . β”‚ β”œβ”€β”€ pixmap_01.raw β”‚ β”œβ”€β”€ /jpeg β”‚ β”‚ β”œβ”€β”€ pixmap_00.jpg β”‚ β”‚ └── pixmap_01.jpg β”‚ └── /png β”‚ β”œβ”€β”€ pixmap_00.png β”‚ └── pixmap_01.png β”œβ”€β”€ /docs β”œβ”€β”€ /programs β”œβ”€β”€ /misc . . . 

Interest Directory: / Users / User / pixmaps

First attemp

 import os import zipfile TARGET_DIRECTORY = "/Users/user/pixmaps" ZIPFILE_NAME = "CompressedDir.zip" def zip_dir(directory, zipname): """ Compress a directory (ZIP file). """ if os.path.exists(directory): outZipFile = zipfile.ZipFile(zipname, 'w', zipfile.ZIP_DEFLATED) for dirpath, dirnames, filenames in os.walk(directory): for filename in filenames: filepath = os.path.join(dirpath, filename) outZipFile.write(filepath) outZipFile.close() if __name__ == '__main__': zip_dir(TARGET_DIRECTORY, ZIPFILE_NAME) 

ZIP file structure:

 CompressedDir.zip . └── /Users └── /user └── /pixmaps β”œβ”€β”€ pixmap_00.raw β”œβ”€β”€ pixmap_01.raw β”œβ”€β”€ /jpeg β”‚ β”œβ”€β”€ pixmap_00.jpg β”‚ └── pixmap_01.jpg └── /png β”œβ”€β”€ pixmap_00.png └── pixmap_01.png 

Avoid full directory path

 def zip_dir(directory, zipname): """ Compress a directory (ZIP file). """ if os.path.exists(directory): outZipFile = zipfile.ZipFile(zipname, 'w', zipfile.ZIP_DEFLATED) # The root directory within the ZIP file. rootdir = os.path.basename(directory) for dirpath, dirnames, filenames in os.walk(directory): for filename in filenames: # Write the file named filename to the archive, # giving it the archive name 'arcname'. filepath = os.path.join(dirpath, filename) parentpath = os.path.relpath(filepath, directory) arcname = os.path.join(rootdir, parentpath) outZipFile.write(filepath, arcname) outZipFile.close() if __name__ == '__main__': zip_dir(TARGET_DIRECTORY, ZIPFILE_NAME) 

ZIP file structure:

 CompressedDir.zip . └── /pixmaps β”œβ”€β”€ pixmap_00.raw β”œβ”€β”€ pixmap_01.raw β”œβ”€β”€ /jpeg β”‚ β”œβ”€β”€ pixmap_00.jpg β”‚ └── pixmap_01.jpg └── /png β”œβ”€β”€ pixmap_00.png └── pixmap_01.png 
+1
source

You can isolate only the file name of your source files using:

 name_file_only= name_full_path.split(os.sep)[-1] 

For example, if name_full_path is /root/files/results/myfile.txt , then name_file_only will be myfile.txt . To archive myfile.txt to the root of the zf archive, you can use:

 zf.write(name_full_path, name_file_only) 
-1
source

Source: https://habr.com/ru/post/981128/


All Articles