簡體   English   中英

正確區分壓縮的.gz文件和存檔的tar.gz文件?

[英]Differentiating between compressed .gz files and archived tar.gz files properly?

解決區分gzip或bzip2格式的純壓縮文件(例如.gz)和使用gzip或bzip2壓縮的tarball(例如.tar.gz)的正確方法是什么,使用后綴擴展名進行識別不是一個可靠的選擇因為文件可能最終會被重命名。

現在,在命令行上,我可以執行以下操作:

bzip2 -dc test.tar.bz2 |head|file -

因此,我嘗試使用以下功能在python中進行類似操作:

def get_magic(self, store_file, buffer=False, look_deeper=False):
    # see what we're indexing
    if look_deeper == True:
        m = magic.Magic(mime=True, uncompress=True)
    else:
        m = magic.Magic(mime=True) 

    if buffer == False:
        try:
            file_type = m.from_file(store_file)

        except Exception, e:
            raise e

    else:
        try:
            file_type = m.from_buffer(store_file)

        except Exception, e:
            raise e

    return file_type 

然后,當嘗試讀取壓縮的tarball時,我將通過以下方式從其他地方傳遞緩沖區:

    file_buffer = open(file_name).read(8096) 
    archive_check = self.get_magic(file_buffer, True, True)

不幸的是,這隨后在python-magic中使用uncompress標志變得很麻煩,因為看起來python-magic希望我傳遞整個文件,即使我只希望它讀取緩沖區。 我最終遇到了一個例外:

bzip2 ERROR: Compressed file ends unexpectedly

看到我要查看的文件的大小最終可能是2M到20GB,這變得相當成問題。 不想讀取整個文件

可以將其砍死並砍掉壓縮文件的末尾並將其附加到緩沖區嗎? 最好忽略使用python-magic解壓縮文件的想法,而是在傳遞緩沖區以通過以下方式進行識別之前執行此操作:

    file_buffer = open(file_name, "r:bz2").read(8096) 

有沒有更好的辦法?

如果偏移量257處的未壓縮數據是“ ustar”, 或者如果未壓縮數據的整體是1024個零字節(空tar文件),則很可能是tar文件。

您可以使用z = zlib.decompressobj()z = bz2.BZ2Decompressor()z.decompress()來僅讀取未壓縮數據的前1024個字節。

實際上,我會將Mark的答案標記為正確的答案,因為它給了我提示。

我最終放棄了該項目以進行其他工作達六個月之久,結果被bz2.BZ2Decompressor所困擾,似乎並未按預期進行。 事實證明,該問題不能用1024字節解決。

#!/usr/bin/env python

import os
import bz2
import magic

store_file = "10mb_test_file.tar.bz2"
m = magic.Magic(mime=True)

file_buffer = open(store_file, "rb").read(1000000)
buffer_chunk = ""

decompressor = bz2.BZ2Decompressor()
print ( "encapsulating bz2" )
print ( type(file_buffer) )
print ( len(file_buffer) )
file_type = m.from_buffer(file_buffer)
print ( "file type: %s :" % file_type)

buffer_chunk += decompressor.decompress( file_buffer )
print ( "compressed file contents" )
print ( type(buffer_chunk) )
print ( len(buffer_chunk) )

file_type = m.from_buffer(buffer_chunk)
print ( "file type: %s :" % file_type)

奇怪的是,對於20MB的tar.bz2文件,我可以使用200,000字節而不是1,000,000字節的值,但是此值在10MB測試文件上不起作用。 我不知道它是否特定於所涉及的tar.bz2存檔,我也沒有研究所涉及的算法是否在特定點,但是到目前為止,大約讀取10MB的數據似乎適用於每個存檔文件到5GB。 一個open()。read(buffer)將讀取緩沖區或EOF的大小,所以可以。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM