正确区分压缩的 .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",则很可能是 tar 文件,如果整个未压缩数据为 1024,则为 或 零字节(空 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 的大小,所以这没问题。
区分 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",则很可能是 tar 文件,如果整个未压缩数据为 1024,则为 或 零字节(空 tar 文件)。
您可以使用 z = zlib.decompressobj()
或 z = bz2.BZ2Decompressor()
和 z.decompress()
.
实际上我打算将 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 的大小,所以这没问题。