我尝试从包含一个文件夹中的子文件夹的.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"
答案 0 :(得分:50)
这将打开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 = file(os.path.join(my_dir, filename), "wb")
with source, target:
shutil.copyfileobj(source, target)
答案 1 :(得分:10)
可以迭代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)
答案 2 :(得分:8)
只需提取到内存中的字节,计算文件名,然后自己编写, 而不是让图书馆这样做 - 通常只使用“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()
答案 3 :(得分:1)
与the solution of Gerhard Götz类似的概念,但适用于提取单个文件而不是整个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)))
答案 4 :(得分:-1)
如果您收到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)