Python 3.x 如何在不解压缩的情况下将zip文件复制到文件夹?
如何使该代码工作? 有一个包含文件夹和.png文件的zip文件。文件夹“\icons\u by\u year”为空。我需要一个接一个地获取每个文件,而无需解压缩,然后将其复制到所选文件夹的根目录下(这样就不会生成额外的文件夹) 我将看一看库的getinfo()和ZipFile.Path()的构造,因为如果您打算进行任何创建,构造函数类也可以以这种方式使用路径 具体地说。这可以做的就是构造一个包含路径的对象,它看起来是基于pathlib的。假设不需要创建ZipFile,可以忽略此ZipFile.Path() 然而,这并不是我想要指出的。而是考虑以下内容: zipfile.getinfo() 我认为有一个人正处于这种情况:Python 3.x 如何在不解压缩的情况下将zip文件复制到文件夹?,python-3.x,zip,zipfile,shutil,Python 3.x,Zip,Zipfile,Shutil,如何使该代码工作? 有一个包含文件夹和.png文件的zip文件。文件夹“\icons\u by\u year”为空。我需要一个接一个地获取每个文件,而无需解压缩,然后将其复制到所选文件夹的根目录下(这样就不会生成额外的文件夹) 我将看一看库的getinfo()和ZipFile.Path()的构造,因为如果您打算进行任何创建,构造函数类也可以以这种方式使用路径 具体地说。这可以做的就是构造一个包含路径的对象,它看起来是基于pathlib的。假设不需要创建ZipFile,可以忽略此ZipFile.P
此人似乎正在使用getinfo()获取路径。很明显,并非每个zipfile都有该信息。
shutil.copyfileobj
将文件对象用于源文件和目标文件。要打开目标,需要为其构造文件路径pathlib
是标准python库的一部分,是处理文件路径的好方法。和ZipFile.extract
执行一些为您创建中间输出目录的工作(加上设置文件元数据),可以用来代替copyfileobj
解压缩文件的一个风险是,它们可能包含目标目录之外的绝对或相对路径(例如“../../badvirus.exe”)extract
在这方面有点太宽松了——将这些文件放在目标目录的根目录中——所以我写了一些东西,如果你被弄乱了,可以拒绝整个zip
用几个Tweek使它成为一个可测试的程序
from pathlib import Path
import re
import zipfile
#import shutil
#class ArrangerOutZip(Arranger):
class ArrangerOutZip:
def __init__(self, base_source_folder, base_output_folder):
self.base_source_folder = Path(base_source_folder).resolve(strict=True)
self.base_output_folder = Path(base_output_folder).resolve()
def proceed(self):
self.create_and_copy()
def create_and_copy(self):
"""Unzip files matching pattern to base_output_folder, raising
ValueError if any resulting paths are outside of that folder.
Output folder created if it does not exist."""
reg_pattern = re.compile('.+\.\w{1,4}$')
with open(self.base_source_folder, 'rb') as f:
with zipfile.ZipFile(f) as zfile:
wanted_files = [cont for cont in zfile.namelist()
if reg_pattern.match(cont)]
rebased_files = self._rebase_paths(wanted_files,
self.base_output_folder)
for cont, rebased in zip(wanted_files, rebased_files):
print(cont, rebased, rebased.parent)
# option 1: use shutil
#rebased.parent.mkdir(parents=True, exist_ok=True)
#with zfile.open(cont) as file, open(rebased, 'wb') as outfile:
# shutil.copyfileobj(file, outfile)
# option 2: zipfile does the work for you
zfile.extract(cont, self.base_output_folder)
@staticmethod
def _rebase_paths(pathlist, target_dir):
"""Rebase relative file paths to target directory, raising
ValueError if any resulting paths are not within target_dir"""
target = Path(target_dir).resolve()
newpaths = []
for path in pathlist:
newpath = target.joinpath(path).resolve()
newpath.relative_to(target) # raises ValueError if not subpath
newpaths.append(newpath)
return newpaths
#arranger = ArrangerOutZip('\\icons.zip', '.\\icons_by_year')
import sys
try:
arranger = ArrangerOutZip(sys.argv[1], sys.argv[2])
arranger.proceed()
except IndexError:
print("usage: test.py zipfile targetdir")
这回答了你的问题吗@不幸的是,没有。我知道如何在两个文件夹之间复制文件。这里的任务是从zip存档文件中逐个复制文件,并将其粘贴到正确创建的文件夹中。文件夹可以像在父类中一样创建,但是我找不到一个正确的解决方案来直接绕过解压从zip文件复制。试试看,出了什么问题?是否有回溯消息?问题是
info.filename
是zipfile中的路径,而不是您的文件系统。您只能在zipfile打开时复制该文件。您可以使用zf.extract
甚至shutil.copyfileobj(zf.open(“任意”),other_fp)
但是由于路径不在您的文件系统上,shutil.copy2
肯定会失败。我不知道如何重新排列您的代码,以便在中使用open(…)作为zf进行复制,但这就是需要发生的事情。我相信在这个cod附近有一个答案,但我无法使它在我的代码中工作:使用ZipFile(“source”,“r”)作为zf:使用zf.open(“destination”,“w”)作为条目:shutil.copyfileobj(source,destination)
我更改了主要问题。我更接近解决方案。您现在可以看一下吗?我相信我在shutil.copyfileobj中传递了错误的数据作为第二个属性。但我不知道如何正确执行此操作=(
from pathlib import Path
import re
import zipfile
#import shutil
#class ArrangerOutZip(Arranger):
class ArrangerOutZip:
def __init__(self, base_source_folder, base_output_folder):
self.base_source_folder = Path(base_source_folder).resolve(strict=True)
self.base_output_folder = Path(base_output_folder).resolve()
def proceed(self):
self.create_and_copy()
def create_and_copy(self):
"""Unzip files matching pattern to base_output_folder, raising
ValueError if any resulting paths are outside of that folder.
Output folder created if it does not exist."""
reg_pattern = re.compile('.+\.\w{1,4}$')
with open(self.base_source_folder, 'rb') as f:
with zipfile.ZipFile(f) as zfile:
wanted_files = [cont for cont in zfile.namelist()
if reg_pattern.match(cont)]
rebased_files = self._rebase_paths(wanted_files,
self.base_output_folder)
for cont, rebased in zip(wanted_files, rebased_files):
print(cont, rebased, rebased.parent)
# option 1: use shutil
#rebased.parent.mkdir(parents=True, exist_ok=True)
#with zfile.open(cont) as file, open(rebased, 'wb') as outfile:
# shutil.copyfileobj(file, outfile)
# option 2: zipfile does the work for you
zfile.extract(cont, self.base_output_folder)
@staticmethod
def _rebase_paths(pathlist, target_dir):
"""Rebase relative file paths to target directory, raising
ValueError if any resulting paths are not within target_dir"""
target = Path(target_dir).resolve()
newpaths = []
for path in pathlist:
newpath = target.joinpath(path).resolve()
newpath.relative_to(target) # raises ValueError if not subpath
newpaths.append(newpath)
return newpaths
#arranger = ArrangerOutZip('\\icons.zip', '.\\icons_by_year')
import sys
try:
arranger = ArrangerOutZip(sys.argv[1], sys.argv[2])
arranger.proceed()
except IndexError:
print("usage: test.py zipfile targetdir")