我的上傳表單需要tar文件,我想檢查上傳的數據是否有效。 tarfile模塊支持is_tarfile()
,但需要一個文件名 - 我不想浪費資源將文件寫入磁盤只是爲了檢查它是否有效。如何確定數據是否是無效的tar文件?
有沒有一種方法來檢查數據是一個有效的tar文件,而不用寫入磁盤,使用標準的Python庫?
我的上傳表單需要tar文件,我想檢查上傳的數據是否有效。 tarfile模塊支持is_tarfile()
,但需要一個文件名 - 我不想浪費資源將文件寫入磁盤只是爲了檢查它是否有效。如何確定數據是否是無效的tar文件?
有沒有一種方法來檢查數據是一個有效的tar文件,而不用寫入磁盤,使用標準的Python庫?
假設您的上傳數據包含在字符串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文檔。
維基百科上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
是如何工作的,並使它適應於檢查你的流而不是文件。源代碼可用here在Python-3.1.1/Lib/tarfile.py
下,但它不適用於微弱的心臟:-)
是否有編碼非ASCII文件名的約定?那篇文章提到了這個問題,但沒有提到一個解決方案。 – 2009-11-24 09:40:06
類TarFile接受fileobj對象。我想你可以通過你從web框架獲得的任何部分下載實體。
__init__(self, name=None, mode='r', fileobj=None)
添加到paxdiablo文章:tar是一個非常困難和複雜的文件格式,儘管其顯而易見。你可以檢查基本約束,但是如果你必須支持所有可能的現有tar方言,你將浪費很多時間。它的大部分複雜性來自於以下幾個問題:
此外,格式沒有前期頭,因此檢查整個歸檔是否理智的唯一方法是完全掃描文件,捕獲每個記錄並驗證每個記錄。
啊,你已經打了我半分鐘:-) – 2009-11-24 06:58:18
不是真的,你的方法是另一種(可能更好)的方式來實現相同。 – 2009-11-24 06:58:53
open
方法tarfile
在其參數fileObj
中取得類似文件的對象。這可以是StringIO
實例
這引出了一個問題:Python的tarfile模塊在直接檢查文件時是否支持與is_tarfile()所討論的不同的tar格式? – Shule 2016-01-29 05:21:20
@Shule要回答這個問題,你可以看一下['is_tarfile()']的模塊源代碼(https://hg.python.org/cpython/file/2.7/Lib/tarfile.py#l2616) 。 – mhawke 2016-01-29 07:11:59