Python中如何使用zipfile压缩文件夹并去除压缩包内的文件路径?
在 /home/Downloads/docs 文件夹中,有很多文件 1.txt 2.txt 3.txt 4.txt ... 压缩为一个 docs.zip 文件包之后,打开这个压缩包,发现里面包含了 /home/Downloads/docs 完整的文件路径。
要怎样去掉 docs.zip 压缩包中的这个 /home/Downloads/docs 路径,打开 docs.zip 压缩包直接显示 1.txt 2.txt 3.txt 4.txt ...
当前代码如下:
import os, zipfile
z = zipfile.ZipFile('docs.zip', 'w', zipfile.ZIP_DEFLATED)
dir = "/home/Downloads/docs"
for root, dirs, files in os.walk(dir):
for file in files:
z.write(os.path.join(root, file))
z.close()
Python中如何使用zipfile压缩文件夹并去除压缩包内的文件路径?
3 回复
import zipfile
import os
from pathlib import Path
def zip_folder_no_path(folder_path, output_zip):
"""
压缩文件夹,但不保留压缩包内的目录结构
Args:
folder_path: 要压缩的文件夹路径
output_zip: 输出的zip文件路径
"""
folder_path = Path(folder_path).resolve()
with zipfile.ZipFile(output_zip, 'w', zipfile.ZIP_DEFLATED) as zipf:
# 遍历文件夹中的所有文件
for root, dirs, files in os.walk(folder_path):
for file in files:
file_path = Path(root) / file
# 计算相对路径(相对于要压缩的文件夹)
rel_path = file_path.relative_to(folder_path)
# 只使用文件名作为压缩包内的路径
# 这样所有文件都会直接放在压缩包的根目录下
zipf.write(file_path, arcname=rel_path.name)
# 使用示例
if __name__ == "__main__":
# 要压缩的文件夹
folder_to_zip = "./my_folder"
# 输出的zip文件
output_file = "compressed_no_path.zip"
# 创建示例文件夹和文件
os.makedirs(folder_to_zip, exist_ok=True)
with open(os.path.join(folder_to_zip, "file1.txt"), "w") as f:
f.write("文件1的内容")
subfolder = os.path.join(folder_to_zip, "subfolder")
os.makedirs(subfolder, exist_ok=True)
with open(os.path.join(subfolder, "file2.txt"), "w") as f:
f.write("文件2的内容")
# 执行压缩
zip_folder_no_path(folder_to_zip, output_file)
print(f"压缩完成: {output_file}")
# 验证压缩包内容
with zipfile.ZipFile(output_file, 'r') as zipf:
print("压缩包内的文件:")
for name in zipf.namelist():
print(f" - {name}")
核心要点:使用arcname参数指定压缩包内的文件名时只传文件名,不传路径。
一句话建议:用arcname=file_path.name让所有文件都进压缩包根目录。
ZipFile.write(filename[, arcname[, compress_type]])
Write the file named filename to the archive, giving it the archive name arcname (by default, this will be the same as filename, but without a drive letter and with leading path separators removed)
先 cd 进去不就行了

