So I'm trying to iterate over a number of files in a tar, and then load that data into some ctype structures's I've defined. Which was working fine with non-tar files, but then I found out that the ExFileObject returned by tarfile's extractfile(member)
method doesn't support the .readinto(b)
method.
So right now here's what I'm doing:
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)
And getting this:
--------------------------------------------------------------------------- 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'
Is there a way that this method can be added to the ExFileObject? Or, is there another way to easily get my data loaded into my defined ctypes structures? I noticed that in the tarfile
object it appears you can set the fileobject
to be used for returned tarinfo files, but just swapping in io.BufferedReader didn't seem to work.
(I tried reading the ExFileObject into StringIO, but it doesn't seem to have readinto()
implemented properly either... I'm thinking I could just extractall()
to a filespace in memory and re-open the files as standard file objects, but I'd like to avoid that since I would then have additional configuration needed)
ExFileObject
doesn't profitedreadinto
method, but you still can do it by reading the header form the file usingread
and copy the data into the structure usingmemmove
:For example:
the string
\x1f\x8b\x08\x08\xad ...
is a tar.gz file contains:after copying that data into
mystruct
it should print: