2009-11-24 58 views
6

我的上傳表單需要tar文件,我想檢查上傳的數據是否有效。 tarfile模塊支持is_tarfile(),但需要一個文件名 - 我不想浪費資源將文件寫入磁盤只是爲了檢查它是否有效。如何確定數據是否是無效的tar文件?

有沒有一種方法來檢查數據是一個有效的tar文件,而不用寫入磁盤,使用標準的Python庫?

回答

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文檔。

+0

這引出了一個問題:Python的tarfile模塊在直接檢查文件時是否支持與is_tarfile()所討論的不同的tar格式? – Shule 2016-01-29 05:21:20

+2

@Shule要回答這個問題,你可以看一下['is_tarfile()']的模塊源代碼(https://hg.python.org/cpython/file/2.7/Lib/tarfile.py#l2616) 。 – mhawke 2016-01-29 07:11:59

4

維基百科上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 

校驗和是通過取報頭塊的無符號字節值的總和與成爲ASCII空間(十進制值32所採取的八個校驗字節計算)。

它被存儲爲一個六位八進制數,前面是零,後面跟着一個空然後是一個空格。

各種實現不遵守這一點,所以依賴於第一個空白空間修剪六位數校驗和會產生更好的兼容性。另外,一些歷史性的tar實現將字節視爲有符號的。

讀者必須計算校驗和兩種方式,並且如果有符號或無符號和與所包含的校驗和相匹配,則視其爲好。

還有UStar格式(在該鏈接中也有詳細說明),但由於它是對舊的tar格式的擴展,所以上面詳述的方法仍然可以工作。 UStar通常只是存儲有關每個文件的額外信息。

另外,由於Python是開源的,你可以看到is_tarfile是如何工作的,並使它適應於檢查你的流而不是文件。源代碼可用herePython-3.1.1/Lib/tarfile.py下,但它不適用於微弱的心臟:-)

+0

是否有編碼非ASCII文件名的約定?那篇文章提到了這個問題,但沒有提到一個解決方案。 – 2009-11-24 09:40:06

3

類TarFile接受fileobj對象。我想你可以通過你從web框架獲得的任何部分下載實體。

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

添加到paxdiablo文章:tar是一個非常困難和複雜的文件格式,儘管其顯而易見。你可以檢查基本約束,但是如果你必須支持所有可能的現有tar方言,你將浪費很多時間。它的大部分複雜性來自於以下幾個問題:

  • 沒有一個真正的標準,直到一個事實標準的存在(USTAR /人)
  • 孔在規範離開供應商的灰色地帶,其中每一個實現自己的解決方案
  • 供應商表示「我們的焦油更好,它將接管t3h世界」
  • 限制以及這些限制的解決方法(例如文件名長度)

此外,格式沒有前期頭,因此檢查整個歸檔是否理智的唯一方法是完全掃描文件,捕獲每個記錄並驗證每個記錄。

+0

啊,你已經打了我半分鐘:-) – 2009-11-24 06:58:18

+0

不是真的,你的方法是另一種(可能更好)的方式來實現相同。 – 2009-11-24 06:58:53

3

open方法tarfile在其參數fileObj中取得類似文件的對象。這可以是StringIO實例

相關問題