tar.extractall() не разпознава неочакван EOF

Библиотеката Python tarfile не открива повреден tar.

user@host$ wc -c good.tar
143360 good.tar

user@host$ head -c 130000 good.tar > cut.tar

user@host$ tar -tf cut.tar 
...
tar: Unexpected EOF in archive
tar: Error is not recoverable: exiting now

Много хубаво, инструментът за команден ред разпознава неочакван EOF.

user@host$ python
Python 2.7.6 (default, Mar 22 2014, 22:59:56) 
>>> import tarfile
>>> tar=tarfile.open('cut.tar')
>>> tar.extractall()

Не е добре. Библиотеката на Python декодира файла, но не създава изключение.

Как да открием неочакван EOF с библиотеката на Python? Искам да избегна модула subprocess.

Параметърът errorlevel не помага. Опитах errorlevel=1 и errorlevel=2.


person guettli    schedule 18.05.2015    source източник
comment
добър улов! трябва да обмислите отварянето на доклад за грешка и да изпратите своето решение   -  person knitti    schedule 21.05.2015
comment
@knitti Отворих доклад за грешка: bugs.python.org/issue24259   -  person guettli    schedule 21.05.2015
comment
За съжаление не мога да добавя награда към съществуваща...   -  person knitti    schedule 21.05.2015
comment
Кой катран използвате? Моят не повдигна грешка.   -  person Ethan Furman    schedule 28.05.2015
comment
Използвам tar (GNU tar) 1.27.1. Докладът за грешка в python.org (вижте по-горе) има повреден tar_which_is_cut.tar за тестване.   -  person guettli    schedule 28.05.2015


Отговори (2)


Написах работа наоколо. Работи с моите tar файлове. Предполагам, че поддържа не всички типове обекти, които могат да се съхраняват в tar файл.

# -*- coding: utf-8 -*-
from __future__ import absolute_import, division, unicode_literals, print_function
import os
import tarfile

class TarfileWhichRaisesOnEOF(tarfile.TarFile):
    def extractall(self, path=".", members=None):
        super(TarfileWhichRaisesOnEOF, self).extractall(path, members)
        if members is None:
            members = self

        for tarinfo in members:
            if not tarinfo.isfile():
                continue
            file=os.path.join(path, tarinfo.name)
            size_real=os.path.getsize(file)
            if size_real!=tarinfo.size:
                raise tarfile.ExtractError('Extracting %s: Size does not match. According to tarinfo %s and on disk %s' % (
                    tarinfo, tarinfo.size, size_real))
person guettli    schedule 18.05.2015

Това е поправено в Python 3 -- OSError се повдига независимо от настройката errorlevel.

person Ethan Furman    schedule 28.05.2015
comment
За съжаление в моя случай настройката на нивото на грешка не работи. Това означава, че промените в Python3 няма да помогнат тук. - person guettli; 29.05.2015
comment
@guettli: опита ли с 3.4? Моля, добавете бележка към bugs.python.org/issue24259, казвайки това. - person Ethan Furman; 30.05.2015
comment
Опитах се да извлека all() качения tar_which_is_cut.tar с Python 3.4.0. Повдига OSError - добре. Само 2.7 засегнати? - person guettli; 30.05.2015