Python: 将二进制文件读入一个结构然后解包
Python: Reading binary file into a structure and then unpacking
我正在将 C++ 代码转换为 python。 C++ 代码读取二进制文件,然后将其转换为不同的字节顺序。我在 python 中遇到同样的问题。有人可以帮助我吗?
这是 C++ 代码:
if( bByteSwap ) // make big-endian
{
pHdr = (UDUMPHDR *)buf;
iAPID = pHdr->sHdr.ccsdsHdr.sW1.uAPID;
iType = pHdr->sHdr.ccsdsHdr.sW7.uFmtID;
iSeqCnt = pHdr->sHdr.ccsdsHdr.uiPktSeq;
for( BYTE *pB=buf; pB<buf+nSz; pB+=2 ) ByteSwap( pB, 2 );
}
else // already big-endian
{
::CopyMemory( buf1, buf, nSz1 );
for( BYTE *pB=buf1; pB<buf1+nSz1; pB+=2 ) ByteSwap( pB, 2 );
pHdr1 = (UDUMPHDR *)buf1;
iAPID = pHdr1->sHdr.ccsdsHdr.sW1.uAPID;
iType = pHdr1->sHdr.ccsdsHdr.sW7.uFmtID;
iSeqCnt = pHdr1->sHdr.ccsdsHdr.uiPktSeq;
}
这里,UDUMPHDR
是一个结构体。我在 python 中使用 ctypes 创建相同的结构,并使用 fileHandle.readinto(s)
函数从二进制文件中读取结构。谁能帮我看看最好的方法是什么?
当前写作Python代码:
class UDUMPHDR(Union):
_fields_ = [("sHdr", TLEDUMPHDR),
("wHdr", WORD * int(sys.getsizeof(TLEDUMPHDR)/2)),
("bHdr", BYTE * sys.getsizeof(TLEDUMPHDR))]
hFile = open(myFile, 'rb')
s = UDUMPHDR()
print("Bytes read:", hFile.readinto(s))
#Make it Big Endian
if(bByteSwap):
print("PktCnt:" + str(s.sHdr.pktHdr.uiPktCnt))
iAPID = s.sHdr.ccsdsHdr.sW1.uAPID
iType = s.sHdr.ccsdsHdr.sW7.uFmtID
iSeqCnt = s.sHdr.ccsdsHdr.uiPktSeq
else:
buf1 = copy.deepcopy(s)
iAPID = buf1.sHdr.ccsdsHdr.sW1.uAPID
iType = buf1.sHdr.ccsdsHdr.sW7.uFmtID
iSeqCnt = buf1.sHdr.ccsdsHdr.uiPktSeq
谢谢。
您复制的大部分代码都是一种非常复杂的字节交换 int16_t
值的方法。 struct
模块可以轻松为您处理,您无需担心。
真正的问题是使用实际布局阅读实际 TLEDUMPHDR
。
比如说,您的结构具有以下布局:
typedef struct TLEDUMPHDR {
int32_t x;
int16_t y;
int16_t z;
} TLEDUMPHDR;
并且您正在从小端读取它并将其写入大端。 format 是 'ihh'
;大端标志是>
,小端标志是<
;因此我们得到:
import struct
buf = bytes([1,2,3,4,5,6,7,8]) # 8 bytes
from_big_endian = struct.unpack('>ihh', buf)
to_little_endian = struct.pack('<ihh', *from_big_endian)
我正在将 C++ 代码转换为 python。 C++ 代码读取二进制文件,然后将其转换为不同的字节顺序。我在 python 中遇到同样的问题。有人可以帮助我吗?
这是 C++ 代码:
if( bByteSwap ) // make big-endian
{
pHdr = (UDUMPHDR *)buf;
iAPID = pHdr->sHdr.ccsdsHdr.sW1.uAPID;
iType = pHdr->sHdr.ccsdsHdr.sW7.uFmtID;
iSeqCnt = pHdr->sHdr.ccsdsHdr.uiPktSeq;
for( BYTE *pB=buf; pB<buf+nSz; pB+=2 ) ByteSwap( pB, 2 );
}
else // already big-endian
{
::CopyMemory( buf1, buf, nSz1 );
for( BYTE *pB=buf1; pB<buf1+nSz1; pB+=2 ) ByteSwap( pB, 2 );
pHdr1 = (UDUMPHDR *)buf1;
iAPID = pHdr1->sHdr.ccsdsHdr.sW1.uAPID;
iType = pHdr1->sHdr.ccsdsHdr.sW7.uFmtID;
iSeqCnt = pHdr1->sHdr.ccsdsHdr.uiPktSeq;
}
这里,UDUMPHDR
是一个结构体。我在 python 中使用 ctypes 创建相同的结构,并使用 fileHandle.readinto(s)
函数从二进制文件中读取结构。谁能帮我看看最好的方法是什么?
当前写作Python代码:
class UDUMPHDR(Union):
_fields_ = [("sHdr", TLEDUMPHDR),
("wHdr", WORD * int(sys.getsizeof(TLEDUMPHDR)/2)),
("bHdr", BYTE * sys.getsizeof(TLEDUMPHDR))]
hFile = open(myFile, 'rb')
s = UDUMPHDR()
print("Bytes read:", hFile.readinto(s))
#Make it Big Endian
if(bByteSwap):
print("PktCnt:" + str(s.sHdr.pktHdr.uiPktCnt))
iAPID = s.sHdr.ccsdsHdr.sW1.uAPID
iType = s.sHdr.ccsdsHdr.sW7.uFmtID
iSeqCnt = s.sHdr.ccsdsHdr.uiPktSeq
else:
buf1 = copy.deepcopy(s)
iAPID = buf1.sHdr.ccsdsHdr.sW1.uAPID
iType = buf1.sHdr.ccsdsHdr.sW7.uFmtID
iSeqCnt = buf1.sHdr.ccsdsHdr.uiPktSeq
谢谢。
您复制的大部分代码都是一种非常复杂的字节交换 int16_t
值的方法。 struct
模块可以轻松为您处理,您无需担心。
真正的问题是使用实际布局阅读实际 TLEDUMPHDR
。
比如说,您的结构具有以下布局:
typedef struct TLEDUMPHDR {
int32_t x;
int16_t y;
int16_t z;
} TLEDUMPHDR;
并且您正在从小端读取它并将其写入大端。 format 是 'ihh'
;大端标志是>
,小端标志是<
;因此我们得到:
import struct
buf = bytes([1,2,3,4,5,6,7,8]) # 8 bytes
from_big_endian = struct.unpack('>ihh', buf)
to_little_endian = struct.pack('<ihh', *from_big_endian)