Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/346.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用python ZipFile从zip中提取文件而不保留结构?_Python_Extract_Unzip_Zipfile - Fatal编程技术网

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

使用python ZipFile从zip中提取文件而不保留结构?,python,extract,unzip,zipfile,Python,Extract,Unzip,Zipfile,我尝试从一个文件夹中包含子文件夹的.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

我尝试从一个文件夹中包含子文件夹的.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"

只需提取内存中的字节,计算文件名,然后自己写在那里, 与其让库来做这件事,不如使用“read()”而不是“extract()”方法:

Python 3.6+更新(2020)-与原始答案相同的代码,但使用了
pathlib.Path
,这简化了文件路径操作和其他操作(如“写入字节”)

从pathlib导入路径
进口拉链
导入操作系统
my_dir=路径(“D:\\Download\”)
my_zip=my_dir/“my_file.zip”
zip_file=zipfile.zipfile(my_-zip,'r')
对于zip_file.namelist()中的文件:
data=zip\u file.read(文件,我的目录)
myfile\u path=my\u dir/path(files.filename).name
我的文件路径。写入字节(数据)
zip_文件.close()
答案中的原始代码不带pathlib:

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

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

导入操作系统
进口舒蒂尔
进口拉链
my_dir=r“D:\下载”
my_zip=r“D:\Download\my_file.zip”
使用zipfile.zipfile(my_-zip)作为zip_文件:
对于zip_文件.namelist()中的成员:
filename=os.path.basename(成员)
#跳过目录
如果不是文件名:
持续
#复制文件(取自zipfile的摘录)
source=zip_file.open(成员)
target=open(os.path.join(my_dir,filename),“wb”)
对于源,目标:
shutil.copyfileobj(源、目标)

可以在
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)

以防出现badZipFile错误。您可以使用7zip子进程解压归档文件。假设您已经安装了7zip,那么请使用以下代码

import subprocess
my_dir = destFolder #destination folder
my_zip = destFolder + "/" + filename.zip #file you want to extract
ziploc = "C:/Program Files/7-Zip/7z.exe" #location where 7zip is installed
cmd = [ziploc, 'e',my_zip ,'-o'+ my_dir ,'*.txt' ,'-r' ] 
#extracting only txt files and from all subdirectories
sp = subprocess.Popen(cmd, stderr=subprocess.STDOUT, stdout=subprocess.PIPE)
与类似的概念,但适用于提取单个文件而不是整个zip文件:

with ZipFile(zipPath, 'r') as zipObj:
    zipInfo = zipObj.getinfo(path_in_zip))
    zipInfo.filename = os.path.basename(destination)
    zipObj.extract(zipInfo, os.path.dirname(os.path.realpath(destination)))

谢谢你。我必须在myfile_路径中添加一个例外以避免目录\并保留文件。我正在使用它,但现在元数据不见了。您知道保存元数据的方法吗?(创建日期时间)这非常有效!但是有没有办法包含子目录呢?子目录是否被正常处理,并在该文件夹中被提取?如果文件名过滤器被调整,则子目录是否比接受的答案更容易,并且也适用于子目录,例如,只提取一个子目录到目标目录。我也更喜欢这个例子,因为它能够通过在fileinfo上使用string.replace方法将目录包含在文件名中,然后提取。zip_info.filename=zip_info.filename.replace(“/”,“”).replace(“:”,“”).replace(“?”,“”)