Jak utworzyć archiwum zip katalogu w Pythonie?

490

Jak mogę utworzyć archiwum zip struktury katalogów w Pythonie?

Martha Yi
źródło
21
Nie używaj rozwiązania sugerowanego w zaakceptowanej odpowiedzi, ale rozwiązania używanego make_archiveod shutil(jeśli chcesz rekurencyjnie skompresować pojedynczy katalog).
malana

Odpowiedzi:

526

Jak zauważyli inni, należy użyć pliku zip . Dokumentacja mówi, jakie funkcje są dostępne, ale tak naprawdę nie wyjaśnia, w jaki sposób można ich użyć do skompresowania całego katalogu. Myślę, że najłatwiej to wyjaśnić za pomocą przykładowego kodu:

#!/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()

Zaadaptowano z: http://www.devshed.com/c/a/Python/Python-UnZipped/

Mark Byers
źródło
129
Dodałbym drugi argument do wywołania zapisu, przekazując os.path.relpath(os.path.join(root, file), os.path.join(path, '..')). Pozwoliłoby to spakować katalog z dowolnego katalogu roboczego, bez uzyskiwania pełnych ścieżek bezwzględnych w archiwum.
Reimund
8
Zabawna rekurencja ma miejsce, gdy próbuję spakować folder i wysłać wynikowy zip do tego samego folderu. :-)
Sibbs Gambling
13
shutilsprawia, że ​​to naprawdę proste w jednej linii. Sprawdź odpowiedź poniżej.
droidlabour
7
możesz być bardziej zainteresowany wykonując ziph.write (os.path.join (ścieżka, plik), arcname = plik), aby nazwy plików w archiwum nie były względem dysku twardego
Christophe Blin
1
Ach, brakowało mi .close()połączenia!
information_interchange
1060

Najprostszym sposobem jest użycie shutil.make_archive. Obsługuje zarówno formaty zip, jak i tar.

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

Jeśli musisz zrobić coś bardziej skomplikowanego niż skompresowanie całego katalogu (np. Pominięcie niektórych plików), musisz przekopać się do zipfilemodułu, jak sugerują inni.

Crdavis
źródło
113
shutiljest częścią standardowej biblioteki python. To powinna być najlepsza odpowiedź
AlexG
4
Jest to najbardziej zwięzła odpowiedź tutaj i ma tę zaletę, że dodaje bezpośrednio wszystkie podkatalogi i pliki do archiwum, zamiast mieć wszystko zawarte w folderze najwyższego poziomu (co powoduje nadmiarowy poziom w strukturze folderów podczas rozpakowywania).
anitch-hat
3
@ cmcginty, czy mógłbyś być bardziej konkretny, który aspekt nie jest bezpieczny dla wątków? Czy uruchomienie wielu wątków podczas wywoływania wywoła awarię interpretera?
std''OrgnlDave
13
Ostrzegamy, że przed Pythonem 3.4 shutil.make_archive nie obsługuje ZIP64 i nie powiedzie się przy tworzeniu plików ZIP większych niż 2 GB.
azdev
2
@Teekin Nie. Jeśli spojrzysz na raport o błędach (bugs.python.org/issue30511), zobaczysz, że shutil.make_archiveużywa os.chdir(). Z tego, co czytam os.chdir(), działa na całym świecie.
Sam Malayek,
65

Aby dodać zawartość mydirectorydo nowego pliku zip, w tym wszystkich plików i podkatalogów:

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()
Ben James
źródło
Dla mnie ten kod rzuca poniżej błędu TypeError: niepoprawny plik: <zipfile.ZipFile [zamknięty]>
Nishad w górę
10
Nie możesz użyć withzamiast dzwonić close()na końcu?
ArtOfWarfare
50

Jak mogę utworzyć archiwum zip struktury katalogów w Pythonie?

W skrypcie Python

W Python 2.7+ shutilma make_archivefunkcję.

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

Tutaj spakowane archiwum zostanie nazwane zipfile_name.zip. Jeśli base_dirjest dalej, root_dirwyklucza pliki, których nie ma w base_dir, ale nadal archiwizuje pliki w katalogach nadrzędnych do root_dir.

Miałem problem z testowaniem tego na Cygwin z wersją 2.7 - chce argumentu root_dir dla cwd:

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

Używanie Pythona z powłoki

Możesz to zrobić za pomocą Pythona z powłoki, również za pomocą zipfilemodułu:

$ python -m zipfile -c zipname sourcedir

Gdzie zipnamejest nazwa żądanego pliku docelowego (dodaj, .zipjeśli chcesz, nie zrobi to automatycznie), a sourcedir to ścieżka do katalogu.

Spakowanie Pythona (lub po prostu nie chcę katalogu nadrzędnego):

Jeśli próbujesz spakować pakiet python za pomocą __init__.pyi __main__.py, a nie chcesz, aby katalog nadrzędny to zrobił

$ python -m zipfile -c zipname sourcedir/*

I

$ python zipname

uruchomiłby pakiet. (Pamiętaj, że nie można uruchamiać podpakietów jako punktu wejścia z skompresowanego archiwum).

Spakowanie aplikacji Python:

Jeśli masz Python3.5 + i szczególnie chcesz spakować pakiet Python, użyj zipapp :

$ python -m zipapp myapp
$ python myapp.pyz
Aaron Hall
źródło
31

Ta funkcja rekurencyjnie spakuje drzewo katalogów, kompresuje pliki i rejestruje poprawne względne nazwy plików w archiwum. Wpisy archiwum są takie same jak te wygenerowane przez 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)
George V. Reilly
źródło
17

Użyj shutil, który jest częścią standardowego zestawu bibliotek Pythona. Korzystanie z shutil jest tak proste (patrz kod poniżej):

  • 1st arg: nazwa pliku wynikowego pliku zip / tar,
  • 2nd arg: zip / tar,
  • Trzeci argument: nazwa_katalogu

Kod:

import shutil
shutil.make_archive('/home/user/Desktop/Filename','zip','/home/username/Desktop/Directory')
vadiraj jahagirdar
źródło
12

Aby dodać kompresję do wynikowego pliku zip, sprawdź ten link .

Musisz zmienić:

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

do

zip = zipfile.ZipFile('Python.zip', 'w', zipfile.ZIP_DEFLATED)
E Smith
źródło
5

Wprowadziłem kilka zmian w kodzie podanym przez Marka Byersa . Poniższa funkcja doda również puste katalogi, jeśli je masz. Przykłady powinny wyjaśnić, jaka jest ścieżka dodana do zip.

#!/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)

Powyżej znajduje się prosta funkcja, która powinna działać w prostych przypadkach. Bardziej eleganckie klasy można znaleźć w mojej Gist: https://gist.github.com/Eccenux/17526123107ca0ac28e6

Nux
źródło
1
Obsługę ścieżki można znacznie uprościć, używając os.path . Zobacz moją odpowiedź.
George V. Reilly,
Błąd: zipHandle.write (os.path.join (root, ".")) Nie bierze pod uwagę basePath.
Petter,
Tak, prawdopodobnie masz rację. Później trochę to ulepszyłem ;-) gist.github.com/Eccenux/17526123107ca0ac28e6
Nux
4

Nowoczesny Python (3.6+) za pomocą pathlib modułu do zwięzłej obsługi ścieżek w stylu OOP oraz pathlib.Path.rglob()do rekurencyjnego globowania. O ile wiem, jest to odpowiednik odpowiedzi George'a V. Reilly'ego: zamki z kompresją, najwyższy element to katalog, utrzymuje puste katalogi, używa względnych ścieżek.

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))

Uwaga: jak wskazują opcjonalne wskazówki typu, zip_namenie może to być obiekt ścieżki ( zostałby naprawiony w wersji 3.6.2+ ).

czas mnicha
źródło
1
Fantastyczny! Zwięzły! Nowoczesny!
ingyhere
3

Mam inny przykład kodu, który może pomóc, używając python3, pathlib i zipfile. Powinien działać w każdym systemie operacyjnym.

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!')
duncanmonty
źródło
1

Oto odmiana odpowiedzi udzielonej przez Nux, która działa dla mnie:

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 )
M. Katz
źródło
1

Wypróbuj poniższy. To działało dla mnie .

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()
Chandra
źródło
1

Jeśli chcesz mieć funkcjonalność taką jak folder kompresji dowolnego popularnego graficznego menedżera plików, możesz użyć następującego kodu, który używa modułu zipfile . Za pomocą tego kodu będziesz mieć plik zip ze ścieżką jako folderem głównym.

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()
VGe0rge
źródło
1

Aby zapewnić większą elastyczność, np. Wybierz katalog / plik według nazwy:

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

W przypadku drzewa plików:

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

Możesz np. Wybrać tylko dir4i 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)

Lub po prostu listdirw katalogu wywołania skryptu i dodaj wszystko stamtąd:

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)
pbn
źródło
To zamyka, ale nie kompresuje.
Alex
1

Powiedz, że chcesz spakować wszystkie foldery (podkatalogi) w bieżącym katalogu.

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))
ShiningGo
źródło
1

Aby w zwięzły sposób zachować hierarchię folderów w katalogu nadrzędnym, który ma zostać zarchiwizowany:

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, ""))

Jeśli chcesz, możesz zmienić to pathlib na globbing plików .

ryanjdillon
źródło
1

Tak wiele odpowiedzi tutaj i mam nadzieję, że mógłbym przyczynić się do mojej własnej wersji, która jest oparta na oryginalnej odpowiedzi (przy okazji), ale z bardziej graficzną perspektywą, również używając kontekstu dla każdej zipfilekonfiguracji i sortowania os.walk(), aby mieć zamówiona moc wyjściowa.

Mając te foldery i pliki (między innymi folderami), chciałem utworzyć .zipdla każdego cap_folderu:

$ 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

Oto, co zastosowałem, z komentarzami dla lepszego zrozumienia procesu.

$ 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) 

Zasadniczo dla każdej iteracji os.walk(path)otwieram kontekst do zipfileinstalacji, a następnie iteruję iterację files, czyli listplik z rootkatalogu, tworząc względną ścieżkę dla każdego pliku na podstawie bieżącego rootkatalogu, dołączając dozipfile kontekstu, który jest uruchomiony .

Dane wyjściowe są prezentowane w następujący sposób:

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

Aby zobaczyć zawartość każdego .zipkatalogu, możesz użyć lesspolecenia:

$ 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
ivanleoncz
źródło
0

Oto nowoczesne podejście, wykorzystujące pathlib i menedżera kontekstu. Umieszcza pliki bezpośrednio w zipie, a nie w podfolderze.

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))
Żółwie są słodkie
źródło
0

Przygotowałem funkcję konsolidując rozwiązanie Marka Byersa z komentarzami Reimunda i Mortena Zilmera (ścieżka względna i puste katalogi). Jako najlepszą praktykęwith stosuje się w konstrukcji pliku ZipFile.

Funkcja przygotowuje również domyślną nazwę pliku zip z nazwą spakowanego katalogu i rozszerzeniem „.zip”. Dlatego działa tylko z jednym argumentem: katalog źródłowy do spakowania.

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)))
Gürol Canbek
źródło
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))
Praveen
źródło
0

Cóż, po przeczytaniu sugestii wymyśliłem bardzo podobny sposób, który działa z wersją 2.7.x bez tworzenia „śmiesznych” nazw katalogów (nazwy absolutne) i utworzę tylko określony folder wewnątrz zip.

Lub na wypadek, gdybyś potrzebował, aby twój zip zawierał folder z zawartością wybranego katalogu.

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" )
Xedret
źródło
0

Funkcja tworzenia pliku zip.

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()
sushh
źródło
proszę wyjaśnij przykładem,
abym
Jednak plik zip „obecnie nie może utworzyć zaszyfrowanego pliku” (z docs.python.org/3.9/library/zipfile.html )
Georg
0

Używanie 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)
sandes
źródło