Как заставить ZipFile заархивировать только указанный каталог — Python 3

Когда я пытаюсь заархивировать каталог с помощью следующего кода, мой каталог заархивирован и содержит все файлы, которые я хотел бы заархивировать, однако он также заархивирует корневые каталоги для каталога, который я хотел бы заархивировать.

(Test — это целевой каталог для архивирования — он содержит другие каталоги и файлы). При распаковке my_python_files.zip он распаковывается с абсолютными путями:

распаковка my_python_files.zip:

\Users\hhafez\Desktop\Test

когда я хотел бы иметь:

\Тест

У меня возникли проблемы с попыткой найти способ избежать этого, любые советы будут высоко оценены.

def get_all_file_paths(directory):
    file_paths = []

    for root, directories, files in os.walk(directory):
        for filename in files:
            filepath = os.path.join(root, filename)
            file_paths.append(filepath)

    return file_paths

def zipfiles():    
    file_paths = get_all_file_paths(r"C:\Users\hhafez\Desktop\Test") 
    with ZipFile('my_python_files.zip','w') as myzip: 
        for file in file_paths:
            print(file)
            myzip.write(file) 

    print('All files zipped successfully!')         

zipfiles()

person Hisham Hafez    schedule 20.03.2019    source источник


Ответы (1)


если вы хотите заархивировать список файлов и не хотите, чтобы zip-архив содержал абсолютные пути каждого файла...

def zipFiles(directory):
    parentDir = "C:\Users\hhafez\Desktop"  #hardcoding parent path to strip
    with ZipFile('my_python_files.zip','w') as myzip: 
        for root, directories, files in os.walk(directory):
            zipFileName = root[len(parentDir):] #always take whats after the parentDir for the filename going in the zip
            for file in files:
                myzip.write(os.path.join(root,file), os.path.join(zipFileName,file), compress_type=zipfile.ZIP_DEFLATED) 


zipfiles(r"C:\Users\hhafez\Desktop\Test")

Это должно выполнить то, что вам нужно. Основным отличием здесь является переменная zipFileName.

 zipFileName = root[len(parentDir):]

Эта строка удаляет parentDir из каталога, который вы просматриваете. zipFileName и имя файла будет именем архива для передачи в myzip.write, что объясняет это:

myzip.write(os.path.join(root,file), os.path.join(zipFileName,file), compress_type=zipfile.ZIP_DEFLATED) 
person Benji Weiss    schedule 20.03.2019
comment
basename, кажется, избавляется от всех каталогов в моем целевом каталоге, я хотел бы оставить все нетронутым в целевом каталоге. - person Hisham Hafez; 20.03.2019
comment
@HishamHafez удалил мою попытку базового имени и изменил мое решение в соответствии с вашим комментарием. - person Benji Weiss; 21.03.2019