Python: 如何在读取多个文件时处理损坏的 gzip 文件

Python: How to handle a corrupted gzip file in reading multiple files

我正在阅读大量 gzip 文件。当我尝试下面的代码时,由于某些文件已损坏,该过程无法完成。 Python 可以打开那些损坏的文件,但由于这些文件中某些行的错误而导致进程中断。

    for file in files:
        try:
            fin=gzip.open(file,'rb')
        except:
            continue
        
        for line in fin:
            try:
                temp=line.decode().split(",")
                a,b,c,d=temp[0],int(temp[1]),int(temp[2]),int(temp[3])
            except:
                continue

但是程序因为以下错误停止了。 处理损坏的 gzip 文件的最佳方法是什么?

Traceback (most recent call last):---------------------------| 9.0% Complete
  File "/opt/anaconda3/lib/python3.7/gzip.py", line 374, in readline
    return self._buffer.readline(size)
  File "/opt/anaconda3/lib/python3.7/_compression.py", line 68, in readinto
    data = self.read(len(byte_view))
  File "/opt/anaconda3/lib/python3.7/gzip.py", line 463, in read
    if not self._read_gzip_header():
  File "/opt/anaconda3/lib/python3.7/gzip.py", line 411, in _read_gzip_header
    raise OSError('Not a gzipped file (%r)' % magic)
OSError: Not a gzipped file (b'rv')

我修改了如下代码,看起来 运行 不错,但不确定这是否是处理此类情况的最佳方式。 因为在某些情况下,程序似乎没有终止(我需要测试更多)。

    for file in files:
        try:
            fin=gzip.open(file,'rb')
        except:
            continue
        
        line=True
        while line:
            try:
                line=fin.readline()
            except:
                continue
            try:
                temp=line.decode().split(",")
                a,b,c,d=temp[0],int(temp[1]),int(temp[2]),int(temp[3])
            except:
                continue

我已经将文件处理部分拆分成一个单独的函数来处理每个文件处理过程中的异常情况。

def proc_file(file):
    try:
        fin=gzip.open(file,'rb')
    except:
        return
        
    err_cnt=0

    while err_cnt<10:
        try:
            line=fin.readline()
        except:
            err_cnt+=1
            continue
        if not line:
            err_cnt+=1
            continue
        try:
            temp=line.decode().split(",")
            a,b,c,d=temp[0],int(temp[1]),int(temp[2]),int(temp[3])
        except:
            continue
    return processed_value

for file in files:

    result=[]
    try:
        value=proc_file(file)
    except:
        continue
    
    result.append(value)

您对文件的迭代在任何 try...except 之外,因此此处引发的异常将终止程序。如果您尝试一次...除了整个事情,那么它应该可以工作:

    for file in files:
        try:
            with gzip.open(file,'rb') as fin:
                for line in fin:
                    temp = line.decode().split(",")
                    a,b,c,d = temp[0], int(temp[1]), int(temp[2]), int(temp[3])
        except OSError, ValueError:
            continue

另请注意:

  • 只捕获我们预期会因错误文件而发生的特定异常,而不是其他仍应终止程序的东西(例如 KeyboardInterrupt)。光秃秃的 except: 通常不是一个好主意。
  • 最好使用 with 构造 gzip.open