2009-11-24 38 views
6

Biểu mẫu tải lên của tôi mong đợi tệp tar và tôi muốn kiểm tra xem dữ liệu đã tải lên có hợp lệ hay không. Mô-đun tarfile hỗ trợ is_tarfile(), nhưng hy vọng tên tệp - tôi không muốn lãng phí tài nguyên ghi tệp vào đĩa chỉ để kiểm tra xem tệp có hợp lệ hay không.Cách xác định xem dữ liệu có phải là tệp tar hợp lệ không có tệp không?

Có cách nào để kiểm tra dữ liệu là tệp tar hợp lệ mà không cần ghi vào đĩa, sử dụng thư viện Python chuẩn không?

Trả lời

3

Giả sử dữ liệu đã tải lên của bạn được chứa trong chuỗi 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" 

Có những phức tạp khác như xử lý các định dạng tệp tar khác nhau và nén. Thông tin thêm có sẵn trong tài liệu tarfile.

+0

Điều này đặt ra câu hỏi: Mô-đun tarfile của Python có hỗ trợ các định dạng tar khác nhau mà bạn đang nói đến với is_tarfile() khi kiểm tra tệp trực tiếp không? – Shule

+2

@Shule Để trả lời câu hỏi đó, bạn có thể xem mã nguồn mô-đun cho ['is_tarfile()'] (https://hg.python.org/cpython/file/2.7/Lib/tarfile.py#l2616) . – mhawke

4

Định dạng tệp tar là here trên Wikipedia.

Tôi nghi ngờ đặt cược tốt nhất của bạn là kiểm tra xem tổng kiểm tra đầu trang cho tệp đầu tiên có hợp lệ hay không. Bạn cũng có thể muốn kiểm tra tên tệp cho tính chính xác nhưng điều đó có thể không đáng tin cậy, tùy thuộc vào tên tệp đã được lưu trữ trong đó.

nhân đôi các thông tin liên quan ở đây:

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 

Các checksum được tính bằng cách lấy tổng của các giá trị byte unsigned của khối đầu với tám byte checksum đưa đến là không gian ASCII (giá trị thập phân 32).

Nó được lưu trữ dưới dạng số bát phân có sáu chữ số với số 0 đứng đầu theo sau là dấu cách và sau đó là dấu cách.

Triển khai khác nhau không tuân theo điều này, do đó, dựa vào không gian màu trắng đầu tiên được cắt sáu chữ số để kiểm tra mang lại khả năng tương thích tốt hơn. Ngoài ra, một số triển khai tar lịch sử đã xử lý các byte như đã ký.

Người đọc phải tính tổng kiểm tra theo cả hai cách và coi nó là tốt nếu số tiền đã ký hoặc chưa ký khớp với tổng kiểm tra được bao gồm.

Ngoài ra còn có định dạng UStar (cũng được nêu chi tiết trong liên kết đó) nhưng vì đó là phần mở rộng cho định dạng tar cũ, phương pháp được nêu chi tiết ở trên vẫn hoạt động. UStar thường chỉ lưu trữ thêm thông tin về mỗi tệp.

Ngoài ra, vì Python là nguồn mở, bạn có thể xem cách hoạt động của is_tarfile và điều chỉnh nó để kiểm tra luồng của bạn chứ không phải tệp. Mã nguồn có sẵn here dưới Python-3.1.1/Lib/tarfile.py nhưng nó không dành cho người yếu tim :-)

+0

Có quy ước để mã hóa tên tệp không phải ASCII không? Bài viết đó đề cập đến vấn đề, nhưng không đề cập đến một giải pháp. –

3

Lớp TarFile chấp nhận đối tượng fileobj. Tôi đoán bạn có thể vượt qua bất kỳ thực thể tải xuống một phần nào bạn nhận được từ khung web của mình.

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

Thêm vào paxdiablo post: tar là định dạng tệp rất khó và phức tạp, mặc dù sự đơn giản rõ ràng của nó. Bạn có thể kiểm tra ràng buộc cơ bản, nhưng nếu bạn phải hỗ trợ tất cả các phương ngữ tar hiện có, bạn sẽ lãng phí rất nhiều thời gian. Hầu hết sự phức tạp của nó xuất phát từ những vấn đề sau:

  • sự vắng mặt của một tiêu chuẩn thực cho đến khi một tiêu chuẩn de-facto tồn tại (UStar/pax)
  • lỗ trong đặc tả lại các nhà cung cấp khu vực màu xám nơi mỗi người thực hiện riêng của họ giải pháp
  • nhà cung cấp nói "tar của chúng tôi tốt hơn và sẽ chiếm lĩnh thế giới t3h"
  • các giới hạn và giải pháp cho những hạn chế này (ví dụ:chiều dài tên tệp)

Ngoài ra, định dạng không có tiêu đề trả trước, do đó cách duy nhất để kiểm tra xem toàn bộ lưu trữ có lành không để quét tệp hoàn toàn, bắt từng bản ghi và xác thực từng tệp.

+0

ah, bạn đã đánh bại tôi một nửa phút :-) –

+0

không thực sự, phương pháp của bạn là một cách khác (có lẽ tốt hơn) để đạt được như vậy. –

3

Phương thức open của tarfile lấy đối tượng giống như tệp trong đối số fileObj của nó. Đây có thể là một ví dụ StringIO

Các vấn đề liên quan