Làm cách nào để tạo một kho lưu trữ zip của một thư mục trong Python?


491

Làm cách nào tôi có thể tạo một kho lưu trữ zip của cấu trúc thư mục trong Python?


21
Không sử dụng giải pháp được đề xuất trong câu trả lời được chấp nhận mà là giải pháp tiếp tục sử dụng make_archivetừ shutil(nếu bạn muốn nén một thư mục theo cách đệ quy).
malana

Câu trả lời:


526

Như những người khác đã chỉ ra, bạn nên sử dụng zipfile . Tài liệu cho bạn biết những chức năng nào có sẵn, nhưng không thực sự giải thích cách bạn có thể sử dụng chúng để nén toàn bộ thư mục. Tôi nghĩ rằng nó dễ nhất để giải thích với một số mã ví dụ:

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

Chuyển thể từ: http://www.devshed.com/c/a/Python/Python-UnZipped/


129
Tôi sẽ thêm một đối số thứ hai vào cuộc gọi viết, thông qua os.path.relpath(os.path.join(root, file), os.path.join(path, '..')). Điều đó sẽ cho phép bạn nén một thư mục từ bất kỳ thư mục làm việc nào, mà không nhận được các đường dẫn tuyệt đối đầy đủ trong kho lưu trữ.
Reimund

8
Có một sự đệ quy hài hước xảy ra khi tôi cố gắng nén một thư mục và xuất zip kết quả vào cùng một thư mục. :-)
Đánh bạc Sibbs 23/03/2017

13
shutillàm cho nó thực sự dễ dàng chỉ trong một dòng duy nhất. Vui lòng kiểm tra câu trả lời bên dưới ..
droidlabour

7
bạn có thể quan tâm hơn bằng cách thực hiện ziph.write (os.path.join (đường dẫn, tệp), arcname = tệp) để tên tệp trong kho lưu trữ không liên quan đến ổ cứng
Barshe Blin

1
Ah, tôi đã bỏ lỡ .close()cuộc gọi!
information_interchange

1063

Cách dễ nhất là sử dụng shutil.make_archive. Nó hỗ trợ cả định dạng zip và tar.

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

Nếu bạn cần phải làm một cái gì đó phức tạp hơn là nén toàn bộ thư mục (chẳng hạn như bỏ qua một số tệp nhất định), thì bạn sẽ cần phải đào sâu vào zipfilemô-đun như những người khác đã đề xuất.


113
shutillà một phần của thư viện python tiêu chuẩn. Đây phải là câu trả lời hàng đầu
AlexG

4
Đây là câu trả lời ngắn gọn nhất ở đây và cũng có lợi thế là thêm trực tiếp tất cả các thư mục con và tệp vào kho lưu trữ, thay vì có tất cả mọi thứ được bao gồm trong một thư mục cấp cao nhất (dẫn đến mức dư thừa trong cấu trúc thư mục khi giải nén).
aitch-hat

3
@cmcginty bạn có thể vui lòng cụ thể hơn một chút về khía cạnh nào của nó không an toàn cho chủ đề không? Sẽ chạy nhiều luồng trong khi một cuộc gọi này làm cho trình thông dịch bị sập?
std''OrgnlDave

13
Được cảnh báo rằng trước Python 3.4, shutil.make_archive không hỗ trợ ZIP64 và sẽ thất bại trong việc tạo các tệp ZIP lớn hơn 2GB.
azdev

2
@Teekin Không. Nếu bạn xem báo cáo lỗi (bug.python.org/su30511), bạn sẽ thấy cách shutil.make_archivesử dụng đó os.chdir(). Từ những gì tôi đang đọc os.chdir(), nó hoạt động trên toàn cầu.
Sam Malayek

65

Để thêm nội dung của mydirectorytệp zip mới, bao gồm tất cả các tệp và thư mục con:

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

Đối với tôi mã này ném bên dưới lỗi LoạiError: tệp không hợp lệ: <zipfile.ZipFile [đã đóng]>
Nishad Up

10
Bạn không thể sử dụng withthay vì phải gọi close()cho mình vào cuối?
ArtOfWarfare

50

Làm cách nào tôi có thể tạo một kho lưu trữ zip của cấu trúc thư mục trong Python?

Trong tập lệnh Python

Trong Python 2.7+, shutilcó một make_archivechức năng.

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

Ở đây kho lưu trữ nén sẽ được đặt tên zipfile_name.zip. Nếu base_dirở xa hơn root_dirnó sẽ loại trừ các tệp không có trong base_dir, nhưng vẫn lưu trữ các tệp trong thư mục gốc lên đến root_dir.

Tôi đã có một vấn đề kiểm tra điều này trên Cygwin với 2.7 - nó muốn có một đối số root_dir, cho cwd:

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

Sử dụng Python từ trình bao

Bạn cũng có thể làm điều này với Python từ trình bao bằng cách sử dụng zipfilemô-đun:

$ python -m zipfile -c zipname sourcedir

Trong trường hợp zipnamelà tên của tập tin đích bạn muốn (thêm .zipnếu bạn muốn nó, nó sẽ không làm điều đó tự động) và SourceDir là đường dẫn đến thư mục.

Nén Python (hoặc chỉ không muốn thư mục gốc):

Nếu bạn đang cố gắng nén một gói python bằng một __init__.py__main__.py, và bạn không muốn thư mục gốc, thì đó là

$ python -m zipfile -c zipname sourcedir/*

$ python zipname

sẽ chạy gói. (Lưu ý rằng bạn không thể chạy các gói con làm điểm vào từ kho lưu trữ được nén.)

Nén ứng dụng Python:

Nếu bạn có python3.5 + và đặc biệt muốn nén gói Python, hãy sử dụng zipapp :

$ python -m zipapp myapp
$ python myapp.pyz

32

Hàm này sẽ nén đệ quy một cây thư mục, nén các tệp và ghi lại tên tệp tương đối chính xác trong kho lưu trữ. Các mục lưu trữ giống như các mục được tạo bởi 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

Sử dụng shutil, một phần của bộ thư viện chuẩn python. Sử dụng shutil rất đơn giản (xem mã bên dưới):

  • 1 arg: Tên tệp của tệp zip / tar kết quả,
  • Đối số thứ 2: zip / tar,
  • Đối số thứ 3: dir_name

Mã số:

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

12

Để thêm nén vào tệp zip kết quả, hãy kiểm tra liên kết này .

Bạn cần thay đổi:

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

đến

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

5

Tôi đã thực hiện một số thay đổi đối với mã do Mark Byers đưa ra . Chức năng bên dưới cũng sẽ thêm các thư mục trống nếu bạn có chúng. Các ví dụ sẽ làm rõ hơn đường dẫn được thêm vào zip là gì.

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

Trên đây là một chức năng đơn giản nên làm việc cho các trường hợp đơn giản. Bạn có thể tìm thấy lớp thanh lịch hơn trong Gist của tôi: https://gist.github.com/Eccenux/17526123107ca0ac28e6


1
Việc xử lý đường dẫn có thể được đơn giản hóa rất nhiều bằng cách sử dụng os.path . Xem câu trả lời của tôi.
George V. Reilly

Lỗi: zipHandle.write (os.path.join (root, ".")) Không xem xét đến BasePath.
Petter

Vâng, bạn có thể đúng. Sau này tôi đã tăng cường điều này một chút ;-) gist.github.com/Eccenux/17526123107ca0ac28e6
Nux

4

Python hiện đại (3.6+) bằng cách sử dụng pathlibmô-đun để xử lý các đường dẫn giống như OOP và pathlib.Path.rglob()để tạo vòng lặp đệ quy. Theo như tôi có thể nói, điều này tương đương với câu trả lời của George V. Reilly: khóa có nén, phần tử trên cùng là một thư mục, giữ các thư mục trống, sử dụng các đường dẫn tương đối.

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

Lưu ý: như gợi ý loại tùy chọn chỉ ra, zip_namekhông thể là đối tượng Đường dẫn ( sẽ được sửa trong 3.6.2+ ).


1
Tuyệt diệu! Ngắn gọn! Hiện đại!
ingyhere

3

Tôi có một ví dụ mã khác có thể giúp đỡ, sử dụng python3, pathlib và zipfile. Nó nên hoạt động trong bất kỳ hệ điều hành.

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

Đây là một biến thể về câu trả lời được đưa ra bởi Nux phù hợp với tôi:

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

Hãy thử một cái dưới đây. Nó làm việc cho tôi .

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

Nếu bạn muốn một chức năng như thư mục nén của bất kỳ trình quản lý tệp đồ họa phổ biến nào, bạn có thể sử dụng mã sau đây, nó sử dụng mô-đun zipfile . Sử dụng mã này, bạn sẽ có tệp zip với đường dẫn là thư mục gốc của nó.

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

Để linh hoạt hơn, ví dụ: chọn thư mục / tệp theo tên sử dụng:

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

Đối với cây tập tin:

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

Bạn có thể chọn, ví dụ chỉ chọn dir4root.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)

Hoặc chỉ listdirtrong thư mục gọi tập lệnh và thêm mọi thứ từ đó:

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)

Khóa này, nhưng không nén.
Alex

1

Giả sử bạn muốn Zip tất cả các thư mục (thư mục con) trong thư mục hiện tại.

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

Đối với một cách ngắn gọn để giữ lại hệ thống phân cấp thư mục trong thư mục mẹ sẽ được lưu trữ:

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

Nếu bạn muốn, bạn có thể thay đổi điều này để sử dụng pathlib cho tập tin toàn cầu .


1

Rất nhiều câu trả lời ở đây và tôi hy vọng tôi có thể đóng góp với phiên bản của riêng mình, dựa trên câu trả lời ban đầu (nhân tiện), nhưng với góc nhìn đồ họa nhiều hơn, cũng sử dụng bối cảnh cho mỗi zipfilethiết lập và sắp xếpos.walk() , để có một sản lượng đặt hàng.

Có các thư mục này và chúng là các tệp (trong số các thư mục khác), tôi muốn tạo một thư mục .zipcho mỗi cap_thư mục:

$ 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

Đây là những gì tôi đã áp dụng, với các ý kiến ​​để hiểu rõ hơn về quy trình.

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

Về cơ bản, với mỗi lần lặp lại os.walk(path), tôi đang mở một bối cảnh để zipfilethiết lập và sau đó, lặp đi lặp lại files, đó là một listtệp từ rootthư mục, tạo thành đường dẫn tương đối cho mỗi tệp dựa trên rootthư mục hiện tại , nối vàozipfile bối cảnh đang chạy .

Và đầu ra được trình bày như thế này:

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

Để xem nội dung của từng .zipthư mục, bạn có thể sử dụng lesslệnh:

$ 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

Đây là một cách tiếp cận hiện đại, sử dụng pathlib và trình quản lý bối cảnh. Đặt các tệp trực tiếp trong zip, thay vì trong thư mục con.

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

Tôi đã chuẩn bị một chức năng bằng cách hợp nhất giải pháp của Mark Byers với các bình luận của Reimund và Morten Zilmer (đường dẫn tương đối và bao gồm các thư mục trống). Như một thực hành tốt nhất,with được sử dụng trong xây dựng tệp của ZipFile.

Hàm này cũng chuẩn bị một tên tệp zip mặc định với tên thư mục được nén và phần mở rộng '.zip'. Do đó, nó chỉ hoạt động với một đối số: thư mục nguồn được nén.

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

Chà, sau khi đọc các gợi ý, tôi đã nghĩ ra một cách rất giống với 2.7.x mà không tạo tên thư mục "buồn cười" (tên giống như tuyệt đối), và sẽ chỉ tạo thư mục được chỉ định bên trong zip.

Hoặc chỉ trong trường hợp bạn cần zip của bạn để chứa một thư mục bên trong với nội dung của thư mục đã chọn.

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

Chức năng tạo tập tin 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()

vui lòng giải thích với một ví dụ để tôi có thể sửa câu trả lời của mình
sushh

Tuy nhiên, zipfile "hiện không thể tạo tệp được mã hóa" (từ docs.python.org/3.9/l Library / zipfile.html )
Georg

0

Sử dụng 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)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.