Python:将二进制文件读入结构然后解压缩

时间:2015-03-22 05:53:55

标签: python c++ endianness

我正在将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

感谢。

1 个答案:

答案 0 :(得分:1)

您复制的大多数代码都是一种非常复杂的字节交换int16_t值的方法。 struct模块可以随时为您处理,因此您无需担心它。

真正的问题是使用其实际布局来阅读实际的TLEDUMPHDR。 比如说,你有一个具有以下布局的结构:

typedef struct TLEDUMPHDR {
    int32_t x;
    int16_t y;
    int16_t z;
} TLEDUMPHDR;

你正在从little-endian读它并把它写成big-endian。 format就是'ihh'; big-endian的标志是>,little-endian是<;因此我们得到:

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)