Python 以静默方式打开不支持的压缩类型的zipfile将返回空filestream,而不是引发异常

Python 以静默方式打开不支持的压缩类型的zipfile将返回空filestream,而不是引发异常,python,zipfile,file-type,Python,Zipfile,File Type,我好像被一个新手的错误打昏了头,而我不是一个新手。 我有一个1.2G已知良好的zipfile“train.zip”,其中包含一个3.5G文件“train.csv”。 我打开zipfile和文件本身,没有任何异常(没有大的zipfile),但是生成的filestream看起来是空的。(UNIX“unzip-c…”确认它是好的) PythonZipFile.open()返回的文件对象不是seek'able或tell'able,因此我无法检查它 Python发行版是2.7.3无EPD的7.3-1(32

我好像被一个新手的错误打昏了头,而我不是一个新手。 我有一个1.2G已知良好的zipfile“train.zip”,其中包含一个3.5G文件“train.csv”。 我打开zipfile和文件本身,没有任何异常(没有大的zipfile),但是生成的filestream看起来是空的。(UNIX“unzip-c…”确认它是好的) Python
ZipFile.open()
返回的文件对象不是seek'able或tell'able,因此我无法检查它

Python发行版是2.7.3无EPD的7.3-1(32位);但是对于大拉链应该没问题。操作系统是MacOS 10.6.6

import csv
import zipfile as zf

zip_pathname = os.path.join('/my/data/path/.../', 'train.zip')
#with zf.ZipFile(zip_pathname).open('train.csv') as z:
z = zf.ZipFile(zip_pathname, 'r', zf.ZIP_DEFLATED, allowZip64=True) # I tried all permutations
z.debug = 1
z.testzip() # zipfile integrity is ok

z1 = z.open('train.csv', 'r') # our file keeps coming up empty?

# Check the info to confirm z1 is indeed a valid 3.5Gb file...
z1i = z.getinfo(file_name)
for att in ('filename', 'file_size', 'compress_size', 'compress_type', 'date_time',  'CRC', 'comment'):
    print '%s:\t' % att, getattr(z1i,att)
# ... and it looks ok. compress_type = 9 ok?
#filename:  train.csv
#file_size: 3729150126
#compress_size: 1284613649
#compress_type: 9
#date_time: (2012, 8, 20, 15, 30, 4)
#CRC:   1679210291

# All attempts to read z1 come up empty?!
# z1.readline() gives ''
# z1.readlines() gives []
# z1.read() takes ~60sec but also returns '' ?

# code I would want to run is:
reader = csv.reader(z1)
header = reader.next()
return reader

原因是:

  • 此文件的压缩类型为类型9:Deflate64/Enhanced Deflate(PKWare的专有格式,而不是更常见的类型8)
  • 还有一个bug:它不会对不受支持的压缩类型抛出异常。它过去只是[第4.4.5节压缩方法]。啊。真是假的。更新:我提交了文件,并在2012年修复,因此当压缩类型未知时,它现在会引发NotImplementedError
一个命令行解决方法是解压缩,然后重新压缩,得到一个普通的类型8:Deflated

出于法律原因,我猜zipfile永远无法实际处理类型9。
Python文档没有提到zipfile不能:(

我处理Python zipfile不支持的压缩类型的解决方案是在zipfile.extractall失败时调用7zip

from zipfile import ZipFile
import subprocess, sys

def Unzip(zipFile, destinationDirectory):
    try:
        with ZipFile(zipFile, 'r') as zipObj:
            # Extract all the contents of zip file in different directory
            zipObj.extractall(destinationDirectory)
    except:
        print("An exception occurred extracting with Python ZipFile library.")
        print("Attempting to extract using 7zip")
        subprocess.Popen(["7z", "e", f"{zipFile}", f"-o{destinationDirectory}", "-y"])

你知道如何检查压缩类型,以便预测无声故障吗?@MartinTaleski:我提出了一个错误,他们解决了它,现在当压缩类型未知时,它会引发NotImplementedError。你可以尝试..catchthat.EAFP physology.Cool。我知道这不适合所有人,但这是一个完美的解决方案我的用例。谢谢!谢谢!请注意,在POSIX系统上,将带有参数的字符串传递给
Popen
构造函数是失败的,因此要使此跨平台,应该传递一个序列而不是字符串,例如
subprocess.Popen([“7z”、“e”、f“{zipFile}”、f“-o{destinationDirectory}”、“y”]))
。很好地看到这里的讨论。您假设
7z
在路径上的某个地方,用户可能会希望为
FileNotFoundError:[Errno 2]添加逻辑以加强这一点,因为没有这样的文件或目录