原文链接:http://www.juzicode.com/python-error-tarfile-append-readerror-invalid-header
错误提示:
tarfile追加文件到压缩包中时提示:ReadError: invalid header, UnicodeDecodeError: ‘ascii’ codec can’t decode byte 0xda in position 0: ordinal not in range(128)
#juzicode.com/vx:桔子code
import tarfile
zf = tarfile.open('test.tar.gz',mode='a')
zf.add('test.csv')
zf.list()
zf.close()
运行结果:
---------------------------------------------------------------------------
UnicodeDecodeError Traceback (most recent call last)
D:\Python\Python38\lib\tarfile.py in nti(s)
185 try:
--> 186 s = nts(s, "ascii", "strict")
187 n = int(s.strip() or "0", 8)
D:\Python\Python38\lib\tarfile.py in nts(s, encoding, errors)
169 s = s[:p]
--> 170 return s.decode(encoding, errors)
171
UnicodeDecodeError: 'ascii' codec can't decode byte 0xda in position 0: ordinal not in range(128)
During handling of the above exception, another exception occurred:
InvalidHeaderError Traceback (most recent call last)
D:\Python\Python38\lib\tarfile.py in __init__(self, name, mode, fileobj, format, tarinfo, dereference, ignore_zeros, encoding, errors, pax_headers, debug, errorlevel, copybufsize)
1517 try:
-> 1518 tarinfo = self.tarinfo.fromtarfile(self)
1519 self.members.append(tarinfo)
D:\Python\Python38\lib\tarfile.py in fromtarfile(cls, tarfile)
1102 buf = tarfile.fileobj.read(BLOCKSIZE)
-> 1103 obj = cls.frombuf(buf, tarfile.encoding, tarfile.errors)
1104 obj.offset = tarfile.fileobj.tell() - BLOCKSIZE
D:\Python\Python38\lib\tarfile.py in frombuf(cls, buf, encoding, errors)
1044
-> 1045 chksum = nti(buf[148:156])
1046 if chksum not in calc_chksums(buf):
D:\Python\Python38\lib\tarfile.py in nti(s)
188 except ValueError:
--> 189 raise InvalidHeaderError("invalid header")
190 return n
InvalidHeaderError: invalid header
During handling of the above exception, another exception occurred:
ReadError Traceback (most recent call last)
<ipython-input-21-0b6340a544d1> in <module>
1 #juzicode.com/vx:桔子code
2 import tarfile
----> 3 zf = tarfile.open('test.tar.gz',mode='a')
4 zf.add('test.csv')
5 zf.list()
D:\Python\Python38\lib\tarfile.py in open(cls, name, mode, fileobj, bufsize, **kwargs)
1635
1636 elif mode in ("a", "w", "x"):
-> 1637 return cls.taropen(name, mode, fileobj, **kwargs)
1638
1639 raise ValueError("undiscernible mode")
D:\Python\Python38\lib\tarfile.py in taropen(cls, name, mode, fileobj, **kwargs)
1645 if mode not in ("r", "a", "w", "x"):
1646 raise ValueError("mode must be 'r', 'a', 'w' or 'x'")
-> 1647 return cls(name, mode, fileobj, **kwargs)
1648
1649 @classmethod
D:\Python\Python38\lib\tarfile.py in __init__(self, name, mode, fileobj, format, tarinfo, dereference, ignore_zeros, encoding, errors, pax_headers, debug, errorlevel, copybufsize)
1522 break
1523 except HeaderError as e:
-> 1524 raise ReadError(str(e))
1525
1526 if self.mode in ("a", "w", "x"):
ReadError: invalid header
错误原因:
1、tarfile模块用open创建文件实例时,不能用mode=’a’模式打开gz,bz2,xz等压缩包,进而不能使用add()方法追加文件,mode=’a’模式只适合tar格式的“压缩”文件。
解决方法:
1、先将文件解压再将解压出来的文件和需要添加的文件生成一个新的压缩文件。
#juzicode.com/vx:桔子code
import tarfile
zf = tarfile.open('test.tar.gz',mode='r')
zf.extractall('unziptar\\')
zf.close()
zf = tarfile.open('test2.tar.gz',mode='w:gz')
zf.add('unziptar\\lena.jpg',arcname='lena.jpg')
zf.add('unziptar\\opencv_text.log',arcname='opencv_text.log')
zf.add('test.csv')
zf.list()
zf.close()
==========运行结果:
-rw-rw-rw- 0/0 91814 2018-02-23 00:38:32 lena.jpg
-rw-rw-rw- 0/0 916 2019-07-18 00:03:24 opencv_text.log
-rw-rw-rw- 0/0 28 2020-10-15 15:08:25 test.csv
扩展内容:
- Python桔子教程
- Python进阶教程m17–压缩解压–zipfile
- Python进阶教程m17b–压缩解压–gzip
- Python进阶教程m17c–压缩解压–lzma
- Python进阶教程m17d–压缩解压–tarfile
如果本文还没有完全解决你的疑惑,你也可以在微信公众号“桔子code”后台给我留言,欢迎一起探讨交流。