gpt4 book ai didi

python - 将 .readinto(b) 方法添加到 tarfile 的 ExFileObject 中?

转载 作者:太空宇宙 更新时间:2023-11-03 18:49:02 26 4
gpt4 key购买 nike

因此,我尝试迭代 tar 中的多个文件,然后将该数据加载到一些 ctype structures's I've defined 中。 。这对于非 tar 文件工作得很好,但后来我发现 ExFileObject tarfile 的 extractfile(member) 方法返回的内容不支持 .readinto(b) 方法。

所以现在这就是我正在做的事情:

import os
import tarfile
import io
from ctypes import c_uint, c_char, c_ubyte, c_ushort, BigEndianStructure

class MyStructure(BigEndianStructure):
_pack_ = True
_fields_ = [
("id", c_uint), # 4 bytes
("namefield", c_char * 32), # 32 bytes
("timestamp", c_ubyte * 4), # 4 bytes
("payload_length", c_ushort), # 2 bytes
]


def process_tar(tar_files):
"""
untar and return file objects to be parsed
"""
for filepath in tar_files:
f = os.path.abspath(filepath)
with tarfile.open(f, 'r:*') as tar_f:
#tar_f.fileobject = io.BufferedReader
for tarinfo_member in tar_f.getmembers():
if tarinfo_member.isfile():
yield tar_f.extractfile(tarinfo_member)

f = "somefiles.tar.gz"
for tar_member_fileobj in process_tar([f]):
mystruct = MyStructure()
tar_member_fileobj.readinto(mystruct)

得到这个:

---------------------------------------------------------------------------  AttributeError                            Traceback (most recent call last) <ipython-input-4-257ee4b46c31> in <module>()
29 for tar_member_fileobj in process_tar([f]):
30 mystruct = MyStructure()
---> 31 tar_member_fileobj.readinto(mystruct)

AttributeError: 'ExFileObject' object has no attribute 'readinto'

有没有办法可以将此方法添加到 ExFileObject 中?或者,是否有另一种方法可以轻松地将我的数据加载到我定义的 ctypes 结构中?我注意到在 tarfile 对象中,您似乎可以将 fileobject 设置为用于返回的 tarinfo 文件,但仅交换 io.BufferedReader 似乎不起作用。

(我尝试将 ExFileObject 读入 StringIO,但它似乎也没有正确实现 readinto()...我想我可以 extractall() 到内存中的文件空间并将文件作为标准文件对象重新打开,但我想避免这种情况,因为这样我就需要额外的配置)

最佳答案

ExFileObject 无法使用 readinto 方法,但您仍然可以通过使用 read 读取文件头并复制使用 memmove 将数据放入结构中:

memmove(byref(mystruct),
tar_member_fileobj.read(sizeof(mystruct)),
sizeof(mystruct)
)

例如:

import os
import tarfile
import io
from ctypes import *

class MyStructure(BigEndianStructure):
_pack_ = True
_fields_ = [
("id", c_uint), # 4 bytes
("namefield", c_char * 32), # 32 bytes
("timestamp", c_ubyte * 4), # 4 bytes
("payload_length", c_ushort), # 2 bytes
]


def process_tar(tar_files):
"""
untar and return file objects to be parsed
"""
for filepath in tar_files:
f = os.path.abspath(filepath)
with tarfile.open(f, 'r:*') as tar_f:
#tar_f.fileobject = io.BufferedReader
for tarinfo_member in tar_f.getmembers():
if tarinfo_member.isfile():
yield tar_f.extractfile(tarinfo_member)



# test tar.gz file
open('somefiles.tar.gz', 'wb').write(
'\x1f\x8b\x08\x08\xad\x5c\x34\x52\x02\x00\x66\x6f\x6f\x2e\x74\
\x61\x72\x00\xed\xca\x49\x0a\x83\x40\x14\x04\xd0\x7f\x85\xdc\
\xa0\x43\x92\x6d\xf8\xdd\xa6\xed\x6d\xe6\xc9\x79\x1e\x76\x82\
\x0a\x82\x4b\xef\x8f\xf6\x42\xf0\x02\x6e\xe4\xbf\x4d\x41\x55\
\xb5\x5d\xdf\x9c\xeb\x6a\xa8\x60\x3d\x1c\x51\x29\xc5\x80\x69\
\xb8\xc8\x99\x14\x8c\x0b\xc1\x25\x4a\x53\x5c\x4c\x5d\x28\x9c\
\xfe\x08\x64\x6d\xbb\xc9\xed\xfe\x78\xbe\xde\x9f\xef\xef\x6f\
\xd9\x8e\xeb\xf9\x41\x18\xc5\x49\x9a\xe5\x45\xb9\xbf\x1e\x8e\
\x27\xd0\xbb\x61\x00\x21\x84\x90\x0d\x19\x01\xd4\xe8\x88\xcf\
\x00\x08\x00\x00'
)

f = "somefiles.tar.gz"
for tar_member_fileobj in process_tar([f]):
mystruct = MyStructure()

memmove(byref(mystruct),
tar_member_fileobj.read(sizeof(mystruct)),
sizeof(mystruct)
)

print hex(mystruct.id)
print mystruct.namefield
print ''.join(map(chr, mystruct.timestamp))
print hex(mystruct.payload_length)

字符串 \x1f\x8b\x08\x08\xad ... 是一个 tar.gz 文件,包含:

\x11\x11\x11\x11ABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%\x00ABCD33

将该数据复制到 mystruct 后,它应该打印:

0x11111111L
ABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%
ABCD
0x3333

关于python - 将 .readinto(b) 方法添加到 tarfile 的 ExFileObject 中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18791003/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com