使用python ZipFile从zip中提取文件而不保留结构?

2024-05-14 19:37:15 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图从一个文件夹中包含子文件夹的.zip中提取所有文件。我希望子文件夹中的所有文件只提取到一个文件夹中,而不保留原始结构。此时,我将全部提取,将文件移动到文件夹中,然后删除以前的子文件夹。同名的文件将被覆盖。

在写文件之前可以这样做吗?

下面是一个结构示例:

my_zip/file1.txt
my_zip/dir1/file2.txt
my_zip/dir1/dir2/file3.txt
my_zip/dir3/file4.txt

最后我要说:

my_dir/file1.txt
my_dir/file2.txt
my_dir/file3.txt
my_dir/file4.txt

我可以在这个代码中添加什么?

import zipfile
my_dir = "D:\\Download\\"
my_zip = "D:\\Download\\my_file.zip"

zip_file = zipfile.ZipFile(my_zip, 'r')
for files in zip_file.namelist():
    zip_file.extract(files, my_dir)
zip_file.close()

如果从zip_file.namelist()重命名文件路径,则会出现以下错误:

KeyError: "There is no item named 'file2.txt' in the archive"

Tags: 文件txt文件夹mydownloaddirzip结构
3条回答

这将打开zip存档成员的文件句柄,提取文件名并将其复制到目标文件(这就是ZipFile.extract的工作方式,而不考虑子目录)。

import os
import shutil
import zipfile

my_dir = r"D:\Download"
my_zip = r"D:\Download\my_file.zip"

with zipfile.ZipFile(my_zip) as zip_file:
    for member in zip_file.namelist():
        filename = os.path.basename(member)
        # skip directories
        if not filename:
            continue

        # copy file (taken from zipfile's extract)
        source = zip_file.open(member)
        target = open(os.path.join(my_dir, filename), "wb")
        with source, target:
            shutil.copyfileobj(source, target)

只需提取内存中的字节,计算文件名,然后自己写下来, 而不是让库来做--通常,只需使用“read()”而不是“extract()”方法:

import zipfile
import os

my_dir = "D:\\Download\\"
my_zip = "D:\\Download\\my_file.zip"

zip_file = zipfile.ZipFile(my_zip, 'r')
for files in zip_file.namelist():
    data = zip_file.read(files, my_dir)
    # I am almost shure zip represents directory separator
    # char as "/" regardless of OS, but I  don't have DOS or Windos here to test it
    myfile_path = os.path.join(my_dir, files.split("/")[-1])
    myfile = open(myfile_path, "wb")
    myfile.write(data)
    myfile.close()
zip_file.close()

可以在ZipFile.infolist()上迭代。在返回的ZipInfo对象上,然后可以操作filename来删除目录部分,最后将其提取到指定的目录。

import glob
import zipfile
import shutil
import os

my_dir = "D:\\Download\\"
my_zip = "D:\\Download\\my_file.zip"

with zipfile.ZipFile(my_zip) as zip:
    for zip_info in zip.infolist():
        if zip_info.filename[-1] == '/':
            continue
        zip_info.filename = os.path.basename(zip_info.filename)
        zip.extract(zip_info, my_dir)

相关问题 更多 >

    热门问题