所以我试图在tar中迭代一些文件,然后将这些数据加载到某些ctype structures's I've defined中。哪个适用于非tar文件,但后来我发现tarfile的extractfile(member)
方法返回的ExFileObject不支持.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()
到内存中的文件空间并重新启动 - 打开文件作为标准文件对象,但我想避免这种情况,因为我需要额外的配置)
答案 0 :(得分:1)
ExFileObject
没有获得readinto
方法,但你仍然可以通过使用read
从文件中读取标题并使用{{1}将数据复制到结构中来实现}:
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)
是tar.gz文件,包含:
\x1f\x8b\x08\x08\xad ...
将这些数据复制到\x11\x11\x11\x11ABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%\x00ABCD33
后,应该打印:
mystruct