我的上传表单需要一个 tar 文件,我想检查上传的数据是否有效。tarfile模块支持,is_tarfile()
但需要一个文件名——我不想浪费资源将文件写入磁盘只是为了检查它是否有效。
有没有办法使用标准 Python 库在不写入磁盘的情况下检查数据是否为有效的 tar 文件?
我的上传表单需要一个 tar 文件,我想检查上传的数据是否有效。tarfile模块支持,is_tarfile()
但需要一个文件名——我不想浪费资源将文件写入磁盘只是为了检查它是否有效。
有没有办法使用标准 Python 库在不写入磁盘的情况下检查数据是否为有效的 tar 文件?
tar 文件格式在Wikipedia 上。
我怀疑您最好的选择是检查第一个文件的标头校验和是否有效。您可能还想检查文件名的完整性,但这可能不可靠,具体取决于存储在其中的文件名。
在此处复制相关信息:
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
但不适合胆小的人:-)
TarFile 类接受一个 fileobj 对象。我想您可以传递从 Web 框架获得的任何部分下载实体。
__init__(self, name=None, mode='r', fileobj=None)
添加到 paxdiablo 帖子:tar 是一种非常困难且复杂的文件格式,尽管它看起来很简单。您可以检查基本约束,但如果您必须支持所有可能的现有 tar 方言,您将浪费大量时间。它的大部分复杂性来自以下问题:
此外,格式没有预先的标题,因此检查整个存档是否正常的唯一方法是完全扫描文件,捕获每条记录,并验证每条记录。
的open
方法tarfile
在其fileObj
参数中接受一个类似文件的对象。这可以是一个StringIO
实例
假设您上传的数据包含在 string 中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文档中提供了更多信息。