Wie erstelle ich ein Zip-Archiv eines Verzeichnisses in Python?


491

Wie kann ich ein Zip-Archiv einer Verzeichnisstruktur in Python erstellen?


21
Verwenden Sie nicht die in der akzeptierten Antwort vorgeschlagene Lösung, sondern die weiter unten verwendete make_archivevon shutil(wenn Sie ein einzelnes Verzeichnis rekursiv komprimieren möchten).
Malana

Antworten:


526

Wie andere bereits betont haben, sollten Sie zipfile verwenden . In der Dokumentation erfahren Sie, welche Funktionen verfügbar sind, es wird jedoch nicht erläutert, wie Sie damit ein gesamtes Verzeichnis komprimieren können. Ich denke, es ist am einfachsten, mit einem Beispielcode zu erklären:

#!/usr/bin/env python
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))

if __name__ == '__main__':
    zipf = zipfile.ZipFile('Python.zip', 'w', zipfile.ZIP_DEFLATED)
    zipdir('tmp/', zipf)
    zipf.close()

Angepasst von: http://www.devshed.com/c/a/Python/Python-UnZipped/


129
Ich würde dem Schreibaufruf ein zweites Argument hinzufügen und übergeben os.path.relpath(os.path.join(root, file), os.path.join(path, '..')). Auf diese Weise können Sie ein Verzeichnis aus einem beliebigen Arbeitsverzeichnis komprimieren, ohne die vollständigen absoluten Pfade im Archiv abzurufen.
Reimund

8
Es gibt eine lustige Rekursion, wenn ich versuche, einen Ordner zu komprimieren und die resultierende Zip-Datei in denselben Ordner auszugeben. :-)
Sibbs Gambling

13
shutilmacht es wirklich einfach in nur einer Zeile. Bitte überprüfen Sie die Antwort unten ..
Droidlabour

7
Sie könnten mehr interessiert sein, wenn Sie ziph.write (os.path.join (Pfad, Datei), arcname = Datei) ausführen, damit die Dateinamen im Archiv nicht relativ zur Festplatte sind
Christophe Blin

1
Ah, ich habe den .close()Anruf verpasst !
information_interchange

1062

Der einfachste Weg ist zu verwenden shutil.make_archive. Es unterstützt sowohl Zip- als auch Teerformate.

import shutil
shutil.make_archive(output_filename, 'zip', dir_name)

Wenn Sie etwas Komplizierteres tun müssen, als das gesamte Verzeichnis zu komprimieren (z. B. bestimmte Dateien zu überspringen), müssen Sie sich zipfilewie von anderen vorgeschlagen in das Modul vertiefen .


113
shutilist Teil der Standard-Python-Bibliothek. Dies sollte die beste Antwort sein
AlexG

4
Dies ist hier die prägnanteste Antwort und hat auch den Vorteil, dass alle Unterverzeichnisse und Dateien direkt zum Archiv hinzugefügt werden, anstatt dass alles in einem Ordner der obersten Ebene enthalten ist (was beim Entpacken zu einer redundanten Ebene in der Ordnerstruktur führt).
Aitch-Hut

3
@cmcginty Könnten Sie bitte etwas genauer sagen, welcher Aspekt davon nicht threadsicher ist? Wird der Interpreter abstürzen, wenn mehrere Threads ausgeführt werden, während einer dies aufruft?
std''OrgnlDave

13
Seien Sie gewarnt, dass shutil.make_archive vor Python 3.4 ZIP64 nicht unterstützt und beim Erstellen von ZIP-Dateien mit mehr als 2 GB fehlschlägt.
Azdev

2
@Teekin Nein. Wenn Sie sich den Fehlerbericht (bugs.python.org/issue30511) ansehen, werden Sie sehen, dass er shutil.make_archiveverwendet wird os.chdir(). Nach dem, worüber ich lese os.chdir(), ist es global tätig.
Sam Malayek

65

So fügen Sie den Inhalt mydirectoryeiner neuen Zip-Datei hinzu, einschließlich aller Dateien und Unterverzeichnisse:

import os
import zipfile

zf = zipfile.ZipFile("myzipfile.zip", "w")
for dirname, subdirs, files in os.walk("mydirectory"):
    zf.write(dirname)
    for filename in files:
        zf.write(os.path.join(dirname, filename))
zf.close()

Für mich wirft dieser Code unter Fehler TypeError: ungültige Datei: <zipfile.ZipFile [geschlossen]>
Nishad Up

10
Kannst du nicht a verwenden, withanstatt close()dich am Ende selbst anrufen zu müssen?
ArtOfWarfare

50

Wie kann ich ein Zip-Archiv einer Verzeichnisstruktur in Python erstellen?

In einem Python-Skript

Hat in Python 2.7+ shutileine make_archiveFunktion.

from shutil import make_archive
make_archive(
  'zipfile_name', 
  'zip',           # the archive format - or tar, bztar, gztar 
  root_dir=None,   # root for archive - current working dir if None
  base_dir=None)   # start archiving from here - cwd if None too

Hier wird das komprimierte Archiv benannt zipfile_name.zip. Wenn base_dires weiter unten root_dirliegt, werden Dateien ausgeschlossen, die sich nicht in der befinden base_dir, aber dennoch die Dateien in den übergeordneten Verzeichnissen bis zum archivieren root_dir.

Ich hatte ein Problem beim Testen auf Cygwin mit 2.7 - es möchte ein root_dir-Argument für cwd:

make_archive('zipfile_name', 'zip', root_dir='.')

Verwenden von Python aus der Shell

Sie können dies mit Python aus der Shell auch mit dem zipfileModul tun :

$ python -m zipfile -c zipname sourcedir

Wo zipnameist der Name der gewünschten .zipZieldatei (hinzufügen, wenn Sie es wollen, wird es nicht automatisch tun) und Sourcedir ist der Pfad zum Verzeichnis.

Python komprimieren (oder einfach kein übergeordnetes Verzeichnis wollen):

Wenn Sie versuchen, ein Python-Paket mit einem __init__.pyund zu komprimieren __main__.py, und Sie das übergeordnete Verzeichnis nicht möchten, ist dies der Fall

$ python -m zipfile -c zipname sourcedir/*

Und

$ python zipname

würde das Paket ausführen. (Beachten Sie, dass Sie keine Unterpakete als Einstiegspunkt aus einem komprimierten Archiv ausführen können.)

Eine Python-App komprimieren:

Wenn Sie Python3.5 + haben und speziell ein Python-Paket komprimieren möchten, verwenden Sie zipapp :

$ python -m zipapp myapp
$ python myapp.pyz

32

Diese Funktion komprimiert rekursiv einen Verzeichnisbaum, komprimiert die Dateien und zeichnet die korrekten relativen Dateinamen im Archiv auf. Die Archiveinträge sind die gleichen wie die von zip -r output.zip source_dir.

import os
import zipfile
def make_zipfile(output_filename, source_dir):
    relroot = os.path.abspath(os.path.join(source_dir, os.pardir))
    with zipfile.ZipFile(output_filename, "w", zipfile.ZIP_DEFLATED) as zip:
        for root, dirs, files in os.walk(source_dir):
            # add directory (needed for empty dirs)
            zip.write(root, os.path.relpath(root, relroot))
            for file in files:
                filename = os.path.join(root, file)
                if os.path.isfile(filename): # regular files only
                    arcname = os.path.join(os.path.relpath(root, relroot), file)
                    zip.write(filename, arcname)

17

Verwenden Sie shutil, das Teil des Python-Standardbibliothekssatzes ist. Die Verwendung von shutil ist so einfach (siehe Code unten):

  • 1. Argument: Dateiname der resultierenden Zip / Tar-Datei,
  • 2. Argument: Reißverschluss / Teer,
  • 3. Argument: dir_name

Code:

import shutil
shutil.make_archive('/home/user/Desktop/Filename','zip','/home/username/Desktop/Directory')

12

Überprüfen Sie diesen Link , um der resultierenden Zip-Datei eine Komprimierung hinzuzufügen .

Du musst dich ändern:

zip = zipfile.ZipFile('Python.zip', 'w')

zu

zip = zipfile.ZipFile('Python.zip', 'w', zipfile.ZIP_DEFLATED)

5

Ich habe einige Änderungen am Code von Mark Byers vorgenommen . Die folgende Funktion fügt auch leere Verzeichnisse hinzu, wenn Sie diese haben. Beispiele sollten klarer machen, welcher Pfad der Zip hinzugefügt wird.

#!/usr/bin/env python
import os
import zipfile

def addDirToZip(zipHandle, path, basePath=""):
    """
    Adding directory given by \a path to opened zip file \a zipHandle

    @param basePath path that will be removed from \a path when adding to archive

    Examples:
        # add whole "dir" to "test.zip" (when you open "test.zip" you will see only "dir")
        zipHandle = zipfile.ZipFile('test.zip', 'w')
        addDirToZip(zipHandle, 'dir')
        zipHandle.close()

        # add contents of "dir" to "test.zip" (when you open "test.zip" you will see only it's contents)
        zipHandle = zipfile.ZipFile('test.zip', 'w')
        addDirToZip(zipHandle, 'dir', 'dir')
        zipHandle.close()

        # add contents of "dir/subdir" to "test.zip" (when you open "test.zip" you will see only contents of "subdir")
        zipHandle = zipfile.ZipFile('test.zip', 'w')
        addDirToZip(zipHandle, 'dir/subdir', 'dir/subdir')
        zipHandle.close()

        # add whole "dir/subdir" to "test.zip" (when you open "test.zip" you will see only "subdir")
        zipHandle = zipfile.ZipFile('test.zip', 'w')
        addDirToZip(zipHandle, 'dir/subdir', 'dir')
        zipHandle.close()

        # add whole "dir/subdir" with full path to "test.zip" (when you open "test.zip" you will see only "dir" and inside it only "subdir")
        zipHandle = zipfile.ZipFile('test.zip', 'w')
        addDirToZip(zipHandle, 'dir/subdir')
        zipHandle.close()

        # add whole "dir" and "otherDir" (with full path) to "test.zip" (when you open "test.zip" you will see only "dir" and "otherDir")
        zipHandle = zipfile.ZipFile('test.zip', 'w')
        addDirToZip(zipHandle, 'dir')
        addDirToZip(zipHandle, 'otherDir')
        zipHandle.close()
    """
    basePath = basePath.rstrip("\\/") + ""
    basePath = basePath.rstrip("\\/")
    for root, dirs, files in os.walk(path):
        # add dir itself (needed for empty dirs
        zipHandle.write(os.path.join(root, "."))
        # add files
        for file in files:
            filePath = os.path.join(root, file)
            inZipPath = filePath.replace(basePath, "", 1).lstrip("\\/")
            #print filePath + " , " + inZipPath
            zipHandle.write(filePath, inZipPath)

Oben ist eine einfache Funktion, die für einfache Fälle funktionieren sollte. Eine elegantere Klasse finden Sie in meinem Gist: https://gist.github.com/Eccenux/17526123107ca0ac28e6


1
Die Pfadbehandlung könnte durch die Verwendung von os.path erheblich vereinfacht werden . Siehe meine Antwort.
George V. Reilly

Fehler: zipHandle.write (os.path.join (root, ".")) Berücksichtigt basePath nicht.
Petter

Ja, du hast wahrscheinlich recht. Ich habe dies später ein wenig erweitert ;-) gist.github.com/Eccenux/17526123107ca0ac28e6
Nux

4

Modernes Python (3.6+) verwendet das pathlibModul zur präzisen OOP-ähnlichen Behandlung von Pfaden und pathlib.Path.rglob()zum rekursiven Globbing. Soweit ich das beurteilen kann, entspricht dies der Antwort von George V. Reilly: Zips mit Komprimierung, das oberste Element ist ein Verzeichnis, hält leere Verzeichnisse, verwendet relative Pfade.

from pathlib import Path
from zipfile import ZIP_DEFLATED, ZipFile

from os import PathLike
from typing import Union


def zip_dir(zip_name: str, source_dir: Union[str, PathLike]):
    src_path = Path(source_dir).expanduser().resolve(strict=True)
    with ZipFile(zip_name, 'w', ZIP_DEFLATED) as zf:
        for file in src_path.rglob('*'):
            zf.write(file, file.relative_to(src_path.parent))

Hinweis: Wie optionale Typhinweise anzeigen, zip_namekann es sich nicht um ein Pfadobjekt handeln (wird in 3.6.2+ behoben ).


1
Fantastisch! Prägnant! Modern!
Ingyhere

3

Ich habe ein anderes Codebeispiel, das mit Python3, Pathlib und Zipfile helfen kann. Es sollte in jedem Betriebssystem funktionieren.

from pathlib import Path
import zipfile
from datetime import datetime

DATE_FORMAT = '%y%m%d'


def date_str():
    """returns the today string year, month, day"""
    return '{}'.format(datetime.now().strftime(DATE_FORMAT))


def zip_name(path):
    """returns the zip filename as string"""
    cur_dir = Path(path).resolve()
    parent_dir = cur_dir.parents[0]
    zip_filename = '{}/{}_{}.zip'.format(parent_dir, cur_dir.name, date_str())
    p_zip = Path(zip_filename)
    n = 1
    while p_zip.exists():
        zip_filename = ('{}/{}_{}_{}.zip'.format(parent_dir, cur_dir.name,
                                             date_str(), n))
        p_zip = Path(zip_filename)
        n += 1
    return zip_filename


def all_files(path):
    """iterator returns all files and folders from path as absolute path string
    """
    for child in Path(path).iterdir():
        yield str(child)
        if child.is_dir():
            for grand_child in all_files(str(child)):
                yield str(Path(grand_child))


def zip_dir(path):
    """generate a zip"""
    zip_filename = zip_name(path)
    zip_file = zipfile.ZipFile(zip_filename, 'w')
    print('create:', zip_filename)
    for file in all_files(path):
        print('adding... ', file)
        zip_file.write(file)
    zip_file.close()


if __name__ == '__main__':
    zip_dir('.')
    print('end!')


1

Hier ist eine Variation der Antwort von Nux, die für mich funktioniert:

def WriteDirectoryToZipFile( zipHandle, srcPath, zipLocalPath = "", zipOperation = zipfile.ZIP_DEFLATED ):
    basePath = os.path.split( srcPath )[ 0 ]
    for root, dirs, files in os.walk( srcPath ):
        p = os.path.join( zipLocalPath, root [ ( len( basePath ) + 1 ) : ] )
        # add dir
        zipHandle.write( root, p, zipOperation )
        # add files
        for f in files:
            filePath = os.path.join( root, f )
            fileInZipPath = os.path.join( p, f )
            zipHandle.write( filePath, fileInZipPath, zipOperation )

1

Probieren Sie die folgende aus. Es hat bei mir funktioniert .

import zipfile, os
zipf = "compress.zip"  
def main():
    directory = r"Filepath"
    toZip(directory)
def toZip(directory):
    zippedHelp = zipfile.ZipFile(zipf, "w", compression=zipfile.ZIP_DEFLATED )

    list = os.listdir(directory)
    for file_list in list:
        file_name = os.path.join(directory,file_list)

        if os.path.isfile(file_name):
            print file_name
            zippedHelp.write(file_name)
        else:
            addFolderToZip(zippedHelp,file_list,directory)
            print "---------------Directory Found-----------------------"
    zippedHelp.close()

def addFolderToZip(zippedHelp,folder,directory):
    path=os.path.join(directory,folder)
    print path
    file_list=os.listdir(path)
    for file_name in file_list:
        file_path=os.path.join(path,file_name)
        if os.path.isfile(file_path):
            zippedHelp.write(file_path)
        elif os.path.isdir(file_name):
            print "------------------sub directory found--------------------"
            addFolderToZip(zippedHelp,file_name,path)


if __name__=="__main__":
    main()

1

Wenn Sie eine Funktionalität wie den Komprimierungsordner eines gängigen grafischen Dateimanagers wünschen, können Sie den folgenden Code verwenden, er verwendet das zipfile- Modul. Mit diesem Code haben Sie die Zip-Datei mit dem Pfad als Stammordner.

import os
import zipfile

def zipdir(path, ziph):
    # Iterate all the directories and files
    for root, dirs, files in os.walk(path):
        # Create a prefix variable with the folder structure inside the path folder. 
        # So if a file is at the path directory will be at the root directory of the zip file
        # so the prefix will be empty. If the file belongs to a containing folder of path folder 
        # then the prefix will be that folder.
        if root.replace(path,'') == '':
                prefix = ''
        else:
                # Keep the folder structure after the path folder, append a '/' at the end 
                # and remome the first character, if it is a '/' in order to have a path like 
                # folder1/folder2/file.txt
                prefix = root.replace(path, '') + '/'
                if (prefix[0] == '/'):
                        prefix = prefix[1:]
        for filename in files:
                actual_file_path = root + '/' + filename
                zipped_file_path = prefix + filename
                zipf.write( actual_file_path, zipped_file_path)


zipf = zipfile.ZipFile('Python.zip', 'w', zipfile.ZIP_DEFLATED)
zipdir('/tmp/justtest/', zipf)
zipf.close()

1

Um mehr Flexibilität zu bieten, z. B. Verzeichnis / Datei nach Namen auswählen, verwenden Sie:

import os
import zipfile

def zipall(ob, path, rel=""):
    basename = os.path.basename(path)
    if os.path.isdir(path):
        if rel == "":
            rel = basename
        ob.write(path, os.path.join(rel))
        for root, dirs, files in os.walk(path):
            for d in dirs:
                zipall(ob, os.path.join(root, d), os.path.join(rel, d))
            for f in files:
                ob.write(os.path.join(root, f), os.path.join(rel, f))
            break
    elif os.path.isfile(path):
        ob.write(path, os.path.join(rel, basename))
    else:
        pass

Für einen Dateibaum:

.
├── dir
   ├── dir2
      └── file2.txt
   ├── dir3
      └── file3.txt
   └── file.txt
├── dir4
   ├── dir5
   └── file4.txt
├── listdir.zip
├── main.py
├── root.txt
└── selective.zip

Sie können zB nur auswählen dir4und root.txt:

cwd = os.getcwd()
files = [os.path.join(cwd, f) for f in ['dir4', 'root.txt']]

with zipfile.ZipFile("selective.zip", "w" ) as myzip:
    for f in files:
        zipall(myzip, f)

Oder einfach listdirim Skriptaufrufverzeichnis und fügen Sie alles von dort hinzu:

with zipfile.ZipFile("listdir.zip", "w" ) as myzip:
    for f in os.listdir():
        if f == "listdir.zip":
            # Creating a listdir.zip in the same directory
            # will include listdir.zip inside itself, beware of this
            continue
        zipall(myzip, f)

Dieser Reißverschluss wird aber nicht komprimiert.
Alex

1

Angenommen, Sie möchten alle Ordner (Unterverzeichnisse) im aktuellen Verzeichnis komprimieren.

for root, dirs, files in os.walk("."):
    for sub_dir in dirs:
        zip_you_want = sub_dir+".zip"
        zip_process = zipfile.ZipFile(zip_you_want, "w", zipfile.ZIP_DEFLATED)
        zip_process.write(file_you_want_to_include)
        zip_process.close()

        print("Successfully zipped directory: {sub_dir}".format(sub_dir=sub_dir))

1

So behalten Sie die Ordnerhierarchie unter dem zu archivierenden übergeordneten Verzeichnis bei:

import glob
import zipfile

with zipfile.ZipFile(fp_zip, "w", zipfile.ZIP_DEFLATED) as zipf:
    for fp in glob(os.path.join(parent, "**/*")):
        base = os.path.commonpath([parent, fp])
        zipf.write(fp, arcname=fp.replace(base, ""))

Wenn Sie möchten, können Sie dies ändern, um es pathlib für das Globbing von Dateien zu verwenden .


1

So viele Antworten hier, und ich hoffe, ich kann mit meiner eigenen Version einen Beitrag leisten, die (übrigens) auf der ursprünglichen Antwort basiert, aber mit einer grafischeren Perspektive, wobei auch der Kontext für jedes zipfileSetup und jede Sortierung verwendet wirdos.walk() , um eine zu haben geordnete Ausgabe.

Mit diesen Ordnern und diesen Dateien (unter anderem) wollte ich .zipfür jeden cap_Ordner eine erstellen :

$ tree -d
.
├── cap_01
|    ├── 0101000001.json
|    ├── 0101000002.json
|    ├── 0101000003.json
|
├── cap_02
|    ├── 0201000001.json
|    ├── 0201000002.json
|    ├── 0201001003.json
|
├── cap_03
|    ├── 0301000001.json
|    ├── 0301000002.json
|    ├── 0301000003.json
| 
├── docs
|    ├── map.txt
|    ├── main_data.xml
|
├── core_files
     ├── core_master
     ├── core_slave

Hier ist, was ich angewendet habe, mit Kommentaren zum besseren Verständnis des Prozesses.

$ cat zip_cap_dirs.py 
""" Zip 'cap_*' directories. """           
import os                                                                       
import zipfile as zf                                                            


for root, dirs, files in sorted(os.walk('.')):                                                                                               
    if 'cap_' in root:                                                          
        print(f"Compressing: {root}")                                           
        # Defining .zip name, according to Capítulo.                            
        cap_dir_zip = '{}.zip'.format(root)                                     
        # Opening zipfile context for current root dir.                         
        with zf.ZipFile(cap_dir_zip, 'w', zf.ZIP_DEFLATED) as new_zip:          
            # Iterating over os.walk list of files for the current root dir.    
            for f in files:                                                     
                # Defining relative path to files from current root dir.        
                f_path = os.path.join(root, f)                                  
                # Writing the file on the .zip file of the context              
                new_zip.write(f_path) 

Grundsätzlich öffne os.walk(path)ich für jede Iteration einen Kontext zum zipfileEinrichten und iteriere anschließend die Iteration files, bei der es sich um eine listDatei aus dem rootVerzeichnis handelt, wobei der relative Pfad für jede Datei basierend auf dem aktuellen rootVerzeichnis gebildet wird und an das angehängt wirdzipfile laufenden Kontext angehängt wird .

Und die Ausgabe wird folgendermaßen dargestellt:

$ python3 zip_cap_dirs.py
Compressing: ./cap_01
Compressing: ./cap_02
Compressing: ./cap_03

Um den Inhalt jedes .zipVerzeichnisses anzuzeigen, können Sie den folgenden lessBefehl verwenden:

$ less cap_01.zip

Archive:  cap_01.zip
 Length   Method    Size  Cmpr    Date    Time   CRC-32   Name
--------  ------  ------- ---- ---------- ----- --------  ----
  22017  Defl:N     2471  89% 2019-09-05 08:05 7a3b5ec6  cap_01/0101000001.json
  21998  Defl:N     2471  89% 2019-09-05 08:05 155bece7  cap_01/0101000002.json
  23236  Defl:N     2573  89% 2019-09-05 08:05 55fced20  cap_01/0101000003.json
--------          ------- ---                           -------
  67251             7515  89%                            3 files

0

Hier ist ein moderner Ansatz mit Pathlib und einem Kontextmanager. Fügt die Dateien direkt in die Zip-Datei und nicht in einen Unterordner ein.

def zip_dir(filename: str, dir_to_zip: pathlib.Path):
    with zipfile.ZipFile(filename, 'w', zipfile.ZIP_DEFLATED) as zipf:
        # Use glob instead of iterdir(), to cover all subdirectories.
        for directory in dir_to_zip.glob('**'):
            for file in directory.iterdir():
                if not file.is_file():
                    continue
                # Strip the first component, so we don't create an uneeded subdirectory
                # containing everything.
                zip_path = pathlib.Path(*file.parts[1:])
                # Use a string, since zipfile doesn't support pathlib  directly.
                zipf.write(str(file), str(zip_path))

0

Ich habe eine Funktion vorbereitet, indem ich die Lösung von Mark Byers mit den Kommentaren von Reimund und Morten Zilmer (relativer Pfad und einschließlich leerer Verzeichnisse) konsolidiert habe. Als Best PracticewithWird bei der Dateikonstruktion von ZipFile verwendet.

Die Funktion bereitet auch einen Standardnamen für die ZIP-Datei mit dem Namen des komprimierten Verzeichnisses und der Erweiterung '.zip' vor. Daher funktioniert es nur mit einem Argument: dem zu komprimierenden Quellverzeichnis.

import os
import zipfile

def zip_dir(path_dir, path_file_zip=''):
if not path_file_zip:
    path_file_zip = os.path.join(
        os.path.dirname(path_dir), os.path.basename(path_dir)+'.zip')
with zipfile.ZipFile(path_file_zip, 'wb', zipfile.ZIP_DEFLATED) as zip_file:
    for root, dirs, files in os.walk(path_dir):
        for file_or_dir in files + dirs:
            zip_file.write(
                os.path.join(root, file_or_dir),
                os.path.relpath(os.path.join(root, file_or_dir),
                                os.path.join(path_dir, os.path.pardir)))

0
# import required python modules
# You have to install zipfile package using pip install

import os,zipfile

# Change the directory where you want your new zip file to be

os.chdir('Type your destination')

# Create a new zipfile ( I called it myfile )

zf = zipfile.ZipFile('myfile.zip','w')

# os.walk gives a directory tree. Access the files using a for loop

for dirnames,folders,files in os.walk('Type your directory'):
    zf.write('Type your Directory')
    for file in files:
        zf.write(os.path.join('Type your directory',file))

0

Nachdem ich die Vorschläge gelesen hatte, kam ich auf eine sehr ähnliche Art und Weise, die mit 2.7.x funktioniert, ohne "lustige" Verzeichnisnamen (absolut ähnliche Namen) zu erstellen, und nur den angegebenen Ordner innerhalb der Zip-Datei erstellt.

Oder nur für den Fall, dass Ihre Zip-Datei einen Ordner mit dem Inhalt des ausgewählten Verzeichnisses enthalten muss.

def zipDir( path, ziph ) :
 """
 Inserts directory (path) into zipfile instance (ziph)
 """
 for root, dirs, files in os.walk( path ) :
  for file in files :
   ziph.write( os.path.join( root, file ) , os.path.basename( os.path.normpath( path ) ) + "\\" + file )

def makeZip( pathToFolder ) :
 """
 Creates a zip file with the specified folder
 """
 zipf = zipfile.ZipFile( pathToFolder + 'file.zip', 'w', zipfile.ZIP_DEFLATED )
 zipDir( pathToFolder, zipf )
 zipf.close()
 print( "Zip file saved to: " + pathToFolder)

makeZip( "c:\\path\\to\\folder\\to\\insert\\into\\zipfile" )

0

Funktion zum Erstellen einer Zip-Datei.

def CREATEZIPFILE(zipname, path):
    #function to create a zip file
    #Parameters: zipname - name of the zip file; path - name of folder/file to be put in zip file

    zipf = zipfile.ZipFile(zipname, 'w', zipfile.ZIP_DEFLATED)
    zipf.setpassword(b"password") #if you want to set password to zipfile

    #checks if the path is file or directory
    if os.path.isdir(path):
        for files in os.listdir(path):
            zipf.write(os.path.join(path, files), files)

    elif os.path.isfile(path):
        zipf.write(os.path.join(path), path)
    zipf.close()

Bitte erklären Sie mit einem Beispiel, damit ich meine Antwort korrigieren kann
Sushh

Zipfile "kann derzeit keine verschlüsselte Datei erstellen" (von docs.python.org/3.9/library/zipfile.html )
Georg

0

Mit zipfly

import zipfly

paths = [
    {
        'fs': '/path/to/large/file'
    },
]

zfly = zipfly.ZipFly( paths = paths )

with open("large.zip", "wb") as f:
    for i in zfly.generator():
        f.write(i)
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.