如何在没有文件的情况下判断数据是否有效的tar文件?
我有一个上传表单,要求上传一个tar文件,我想检查一下上传的数据是否有效。Python的tarfile模块有一个is_tarfile()
的功能,但它需要一个文件名——我不想浪费资源把文件写到硬盘上,只是为了检查它是否有效。
有没有办法在不写入硬盘的情况下,使用标准的Python库来检查数据是否是一个有效的tar文件呢?
4 个回答
tarfile
的open
方法需要一个类似文件的对象作为它的fileObj
参数。这个对象可以是一个StringIO
实例。
tar文件格式的详细信息可以在维基百科上找到。
我觉得你可以先检查一下第一个文件的头部校验和是否有效。你也可以检查一下文件名是否正常,但这可能不太可靠,因为里面存储的文件名可能会有问题。
这里重复一下相关信息:
Offset Size Description
0 100 File name
100 8 File mode
108 8 Owner's numeric user ID
116 8 Group's numeric user ID
124 12 File size in bytes
136 12 Last modification time in numeric Unix time format
148 8 Checksum for header block
156 1 Link indicator (file type)
157 100 Name of linked file
校验和是通过将头部块中无符号字节值的总和计算出来的,同时把八个校验字节当作ASCII空格(十进制值32)来处理。
它以六位八进制数字的形式存储,前面可能有零,然后是一个空字符和一个空格。
不同的实现可能不遵循这个规则,所以依赖于去掉前导空格的六位数字来计算校验和会更兼容。此外,一些早期的tar实现将字节视为有符号的。
读取者必须两种方式都计算校验和,如果有符号或无符号的总和与包含的校验和匹配,就可以认为是有效的。
还有UStar格式(在那个链接中也有详细说明),但由于它是对旧tar格式的扩展,上面提到的方法仍然适用。UStar主要是用来存储每个文件的额外信息。
另外,由于Python是开源的,你可以看看is_tarfile
是怎么工作的,然后调整它来检查你的数据流,而不是文件。源代码可以在这里找到,路径是Python-3.1.1/Lib/tarfile.py
,不过这对初学者来说可能有点难哦:-)
假设你上传的数据存储在一个叫 data
的字符串里。
from tarfile import TarFile, TarError
from StringIO import StringIO
sio = StringIO(data)
try:
tf = TarFile(fileobj=sio)
# process the file....
except TarError:
print "Not a tar file"
还有一些额外的复杂情况,比如处理不同的tar文件格式和压缩方式。如果你想了解更多,可以查看 tarfile 的文档。