如何确定数据是否是没有文件的有效tar文件?

时间:2009-11-24 06:31:09

标签: python tar tarfile

我的上传表单需要tar文件,我想检查上传的数据是否有效。 tarfile模块支持is_tarfile(),但需要一个文件名 - 我不想浪费资源将文件写入磁盘只是为了检查它是否有效。

有没有办法使用标准Python库检查数据是否是有效的tar文件而无需写入磁盘?

4 个答案:

答案 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方言,您将浪费大量时间。其大部分复杂性来自以下问题:

  • 缺乏真正的标准,直到存在事实上的标准(UStar / pax)
  • 规范中的漏洞使供应商出现了灰色区域,每个区域都实现了自己的解决方案
  • 供应商说“我们的焦油更好,它将接管t3h世界”
  • 这些限制的限制和解决方法(例如文件名长度)

此外,格式没有前端标头,因此检查整个存档是否合理的唯一方法是完全扫描文件,捕获每条记录并验证每个记录。

答案 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文档。