在没有绝对路径的 Python 3.6 中写入 zipfile
Writing zipfile in Python 3.6 without absolute path
我正在尝试使用 Python 的 zipfile
模块编写一个 zip 文件,该模块从某个子文件夹开始,但仍保持该子文件夹的树结构。例如,如果我传递“C:\Users\User1\OneDrive\Documents”,zip 文件将包含从 Documents 开始的所有内容,所有 Documents 的子文件夹都保留在 Documents 中。我有以下代码:
import zipfile
import os
import datetime
def backup(src, dest):
"""Backup files from src to dest."""
base = os.path.basename(src)
now = datetime.datetime.now()
newFile = f'{base}_{now.month}-{now.day}-{now.year}.zip'
# Set the current working directory.
os.chdir(dest)
if os.path.exists(newFile):
os.unlink(newFile)
newFile = f'{base}_{now.month}-{now.day}-{now.year}_OVERWRITE.zip'
# Write the zipfile and walk the source directory tree.
with zipfile.ZipFile(newFile, 'w') as zip:
for folder, _ , files in os.walk(src):
print(f'Working in folder {os.path.basename(folder)}')
for file in files:
zip.write(os.path.join(folder, file),
arcname=os.path.join(
folder[len(os.path.dirname(folder)) + 1:], file),
compress_type=zipfile.ZIP_DEFLATED)
print(f'\n---------- Backup of {base} to {dest} successful! ----------\n')
我知道我必须为 zipfile.write() 使用 arcname
参数,但我不知道如何获取它来维护原始目录的树结构。现在的代码会将每个子文件夹写入 zip 文件的第一层(如果有意义的话)。我读过一些 post 的建议,建议我使用 os.path.relname() 来切断根,但我似乎无法弄清楚如何正确地做到这一点。我还知道这个 post 看起来与 Stack Overflow 上的其他人相似。我已经阅读了其他 posts,但无法弄清楚如何解决这个问题。
arcname 参数将为您要添加的文件设置 zip 文件中的确切路径。您的问题是,当您为 arcname 构建路径时,您使用了错误的值来获取要删除的前缀的长度。具体来说:
arcname=os.path.join(folder[len(os.path.dirname(folder)) + 1:], file)
应改为:
arcname=os.path.join(folder[len(src):], file)
我正在尝试使用 Python 的 zipfile
模块编写一个 zip 文件,该模块从某个子文件夹开始,但仍保持该子文件夹的树结构。例如,如果我传递“C:\Users\User1\OneDrive\Documents”,zip 文件将包含从 Documents 开始的所有内容,所有 Documents 的子文件夹都保留在 Documents 中。我有以下代码:
import zipfile
import os
import datetime
def backup(src, dest):
"""Backup files from src to dest."""
base = os.path.basename(src)
now = datetime.datetime.now()
newFile = f'{base}_{now.month}-{now.day}-{now.year}.zip'
# Set the current working directory.
os.chdir(dest)
if os.path.exists(newFile):
os.unlink(newFile)
newFile = f'{base}_{now.month}-{now.day}-{now.year}_OVERWRITE.zip'
# Write the zipfile and walk the source directory tree.
with zipfile.ZipFile(newFile, 'w') as zip:
for folder, _ , files in os.walk(src):
print(f'Working in folder {os.path.basename(folder)}')
for file in files:
zip.write(os.path.join(folder, file),
arcname=os.path.join(
folder[len(os.path.dirname(folder)) + 1:], file),
compress_type=zipfile.ZIP_DEFLATED)
print(f'\n---------- Backup of {base} to {dest} successful! ----------\n')
我知道我必须为 zipfile.write() 使用 arcname
参数,但我不知道如何获取它来维护原始目录的树结构。现在的代码会将每个子文件夹写入 zip 文件的第一层(如果有意义的话)。我读过一些 post 的建议,建议我使用 os.path.relname() 来切断根,但我似乎无法弄清楚如何正确地做到这一点。我还知道这个 post 看起来与 Stack Overflow 上的其他人相似。我已经阅读了其他 posts,但无法弄清楚如何解决这个问题。
arcname 参数将为您要添加的文件设置 zip 文件中的确切路径。您的问题是,当您为 arcname 构建路径时,您使用了错误的值来获取要删除的前缀的长度。具体来说:
arcname=os.path.join(folder[len(os.path.dirname(folder)) + 1:], file)
应改为:
arcname=os.path.join(folder[len(src):], file)