我的上传表单需要tar文件,我想检查上传的数据是否有效。 tarfile模块支持is_tarfile()
,但需要一个文件名 - 我不想浪费资源将文件写入磁盘只是为了检查它是否有效。
有没有办法使用标准Python库检查数据是否是有效的tar文件而无需写入磁盘?
答案 0 :(得分:5)
维基百科上的tar文件格式为here。
我怀疑你最好的选择是检查第一个文件的标头校验和是否有效。您可能还需要检查文件名是否合理,但可能不可靠,具体取决于已存储在其中的文件名。
在此处复制相关信息:
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
校验和的计算方法是将标题块的无符号字节值与8个校验和字节之和取为ASCII空格(十进制值32)。
它存储为六位八进制数,前导零后跟空,然后是空格。
各种实现都不遵循这一点,因此依靠第一个空白区域修剪六位数作为校验和会产生更好的兼容性。此外,一些历史性的tar实现将字节视为已签名。
读者必须以两种方式计算校验和,如果有符号或无符号的和与所包含的校验和匹配,则将其视为好。
还有UStar格式(在该链接中也有详细说明)但是,由于它是旧tar格式的扩展,因此上面详述的方法仍然有效。 UStar通常只是存储有关每个文件的额外信息。
或者,由于Python是开源的,您可以看到is_tarfile
如何工作并调整它以检查您的流而不是文件。源代码在Python-3.1.1/Lib/tarfile.py
下可用here,但不适合胆小的人: - )
答案 1 :(得分:3)
类TarFile接受fileobj对象。我想你可以通过你从web框架获得的任何部分下载实体。
__init__(self, name=None, mode='r', fileobj=None)
添加到paxdiablo帖子:tar是一种非常困难和复杂的文件格式,尽管它显而易见。您可以检查基本约束,但如果您必须支持所有可能的现有tar方言,您将浪费大量时间。其大部分复杂性来自以下问题:
此外,格式没有前端标头,因此检查整个存档是否合理的唯一方法是完全扫描文件,捕获每条记录并验证每个记录。
答案 2 :(得分:3)
open
的{{1}}方法在其tarfile
参数中采用类似文件的对象。这可以是fileObj
实例
答案 3 :(得分:3)
假设您上传的数据包含在字符串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文档。