Как игнорировать ошибки zlib в EOF?

Мне нужен мой Python-скрипт для работы с gzip-файлами, которые все еще могут быть записаны. Поскольку они еще не были должным образом закрыты, такие операции иногда приводят к ошибкам CRC в конце.

Как подавить эти ошибки и просто обработать все до неполной концовки?

Мой код:

if usegzip:
    opener = gzip.open;
else:
    opener = open;

...
for line in opener(input_filename,'r'):
    .... process line ....

Исключение, которое я получаю, когда встречается все еще открытый файл:

    for line in opener(input_filename,'r'):
  File "/opt/lib/python2.7/gzip.py", line 464, in readline
    c = self.read(readsize)
  File "/opt/lib/python2.7/gzip.py", line 268, in read
    self._read(readsize)
  File "/opt/lib/python2.7/gzip.py", line 315, in _read
    self._read_eof()
  File "/opt/lib/python2.7/gzip.py", line 354, in _read_eof
    hex(self.crc)))
IOError: CRC check failed 0x7248907 != 0x45e82dc4L

Могу ли я каким-то образом подавить его, не переопределяя gzip-модуль?


person Mikhail T.    schedule 09.01.2018    source источник
comment
посмотрите здесь   -  person sKwa    schedule 10.01.2018
comment
Спасибо. Да, это та же ошибка, но zlib-модуль сам по себе не предоставить интерфейс, подходящий для замены. Нет zlib.open() и друзей...   -  person Mikhail T.    schedule 10.01.2018


Ответы (1)


Хорошо, решение состоит в том, чтобы отказаться от удобства цикла for и явно перебирать строки. Затем явную итерацию можно поместить внутрь try/except для обработки ошибок. Например, вот простой счетчик строк внутри сжатого gzip-файла:

import gzip
import sys

f = sys.argv[-1]
count = 0
opener = gzip.open

lines = opener(f) # Creates the iterator normally used by for-loop

while 1:
    try:
        line = lines.next()
    except (IOError, StopIteration):
        break
    count += 1

print count

Когда файл правильно закрыт, вывод вышеприведенного скрипта такой же, как у gzcat | wc -l. Но, когда файл все еще записывается, скрипт может успешно прочитать больше строк, чем gzcat.

person Mikhail T.    schedule 09.01.2018