8

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

有没有办法使用标准 Python 库在不写入磁盘的情况下检查数据是否为有效的 tar 文件?

4

4 回答 4

5

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但不适合胆小的人:-)

于 2009-11-24T06:37:45.237 回答
3

TarFile 类接受一个 fileobj 对象。我想您可以传递从 Web 框架获得的任何部分下载实体。

__init__(self, name=None, mode='r', fileobj=None)

添加到 paxdiablo 帖子:tar 是一种非常困难且复杂的文件格式,尽管它看起来很简单。您可以检查基本约束,但如果您必须支持所有可能的现有 tar 方言,您将浪费大量时间。它的大部分复杂性来自以下问题:

  • 在事实上的标准存在之前没有真正的标准(UStar/pax)
  • 规范中的漏洞使供应商处于灰色区域,每个供应商都实施了自己的解决方案
  • 供应商说“我们的 tar 更好,它将接管 t3h 世界”
  • 限制,以及这些限制的解决方法(例如文件名长度)

此外,格式没有预先的标题,因此检查整个存档是否正常的唯一方法是完全扫描文件,捕获每条记录,并验证每条记录。

于 2009-11-24T06:56:18.943 回答
3

open方法tarfile在其fileObj参数中接受一个类似文件的对象。这可以是一个StringIO实例

于 2009-11-24T06:57:25.183 回答
3

假设您上传的数据包含在 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文档中提供了更多信息。

于 2009-11-24T07:08:50.370 回答