在不完全提取的情况下读取 tarfile 中的大文件头 (~9GB)
Read large file header (~9GB) inside tarfile without full extraction
我有 ~1GB *.tbz 文件。在这些文件中的每一个中,都有一个大约 9GB 的文件。我只需要读取这个文件的头,前 1024 个字节。
我希望它尽可能快地执行此操作,因为我有数百个要处理的 1GB 文件。提取大约需要 1 分 30 秒。
我尝试使用完全提取:
tar = tarfile.open(fn, mode='r|bz2')
for item in tar:
tar.extract(item)
和tarfile.getmembers()
但没有速度改进:
tar = tarfile.open(fn, mode='r|bz2')
for member in tar.getmembers():
f = tar.extractfile(member)
headerbytes = f.read(1024)
headerdict = parseHeader(headerbytes)
getmembers()
方法一直在那里。
有什么办法吗?
如果您确定每个 tar 存档只包含一个 bz2 文件,您可以在第一次读取 tar 文件时跳过前 512 个字节(不是包含的 bz2 文件当然,在其中),因为 tar 文件格式有一个填充(固定大小)header,之后您的 "real" 内容被存储。
一个简单的
f.seek(512)
而不是遍历 getmembers() 应该可以做到这一点。
我认为你应该使用标准库 bz2
接口。 .tbz
是 tar
文件的文件扩展名,这些文件使用 -j
选项压缩以指定 bzip2
格式。
作为 @bbayles pointed out in the comments, you can open your file as a bz2.BZ2File
并使用 seek
和 read
:
read([size])
Read at most size uncompressed bytes, returned as a
string. If the size argument is negative or omitted, read until EOF is
reached.
seek(offset[, whence])
Move to new file position. Argument offset is a
byte count.
f = bz2.BZ2File(path)
f.seek(512)
headerbytes = f.read(1024)
然后您可以使用您的函数对其进行解析。
headerdict = parseHeader(headerbytes)
我有 ~1GB *.tbz 文件。在这些文件中的每一个中,都有一个大约 9GB 的文件。我只需要读取这个文件的头,前 1024 个字节。
我希望它尽可能快地执行此操作,因为我有数百个要处理的 1GB 文件。提取大约需要 1 分 30 秒。
我尝试使用完全提取:
tar = tarfile.open(fn, mode='r|bz2')
for item in tar:
tar.extract(item)
和tarfile.getmembers()
但没有速度改进:
tar = tarfile.open(fn, mode='r|bz2')
for member in tar.getmembers():
f = tar.extractfile(member)
headerbytes = f.read(1024)
headerdict = parseHeader(headerbytes)
getmembers()
方法一直在那里。
有什么办法吗?
如果您确定每个 tar 存档只包含一个 bz2 文件,您可以在第一次读取 tar 文件时跳过前 512 个字节(不是包含的 bz2 文件当然,在其中),因为 tar 文件格式有一个填充(固定大小)header,之后您的 "real" 内容被存储。
一个简单的
f.seek(512)
而不是遍历 getmembers() 应该可以做到这一点。
我认为你应该使用标准库 bz2
接口。 .tbz
是 tar
文件的文件扩展名,这些文件使用 -j
选项压缩以指定 bzip2
格式。
作为 @bbayles pointed out in the comments, you can open your file as a bz2.BZ2File
并使用 seek
和 read
:
read([size])
Read at most size uncompressed bytes, returned as a string. If the size argument is negative or omitted, read until EOF is reached.
seek(offset[, whence])
Move to new file position. Argument offset is a byte count.
f = bz2.BZ2File(path)
f.seek(512)
headerbytes = f.read(1024)
然后您可以使用您的函数对其进行解析。
headerdict = parseHeader(headerbytes)