1

我有一个包含许多部分的二进制文件。每个部分都有自己的模式(即整数、浮点数和字符串的放置)。

每个部分的模式是已知的。但是,该模式在该部分中出现的次数是未知的。每条记录都在两个相同的整数之间。这些整数表示记录的大小。部分名称位于两个整数记录长度变量之间:8 和 8。此外,在每个部分中,有多个记录(已知)。

Header
---------------------
Known header pattern
---------------------
8 Section One 8
---------------------
Section One pattern repeating i times
---------------------
8 Section Two 8
---------------------
Section Two pattern repeating j times
---------------------
8 Section Three 8
---------------------
Section Three pattern repeating k times
---------------------

这是我的方法:

  1. 使用 循环并读取每条记录f.read(record_length),如果记录是 8 字节,则转换为字符串,这将是节名称。

  2. 然后我打电话:np.fromfile(file,dtype=section_pattern,count=n)

我呼吁np.fromfile每个部分。

我遇到的问题有两个:

  1. 如何在不进行第一遍阅读的情况下确定每个部分的 n?
  2. 读取每条记录以查找节名似乎相当低效。有没有更有效的方法来实现这一点?

部分名称始终位于两个整数记录变量之间:8 和 8。

这是一个示例代码,请注意,在这种情况下,我不必指定计数,因为 OES 部分是最后一部分:

with open('m13.op2', "rb") as f:

    filesize = os.fstat(f.fileno()).st_size
    f.seek(108,1) # skip header

    while True:

        rec_len_1 = unpack_int(f.read(4))
        record_bytes = f.read(rec_len_1)
        rec_len_2 = unpack_int(f.read(4))
        record_num = record_num + 1

        if rec_len_1==8:

            tablename = unpack_string(record_bytes).strip()

            if tablename == 'OES':

                OES = [

                # Top keys
                ('1','i4',1),('op2key7','i4',1),('2','i4',1),
                ('3','i4',1),('op2key8','i4',1),('4','i4',1),
                ('5','i4',1),('op2key9','i4',1),('6','i4',1),

                # Record 2 -- IDENT
                ('7','i4',1),('IDENT','i4',1),('8','i4',1),
                ('9','i4',1),
                ('acode','i4',1),
                ('tcode','i4',1),
                ('element_type','i4',1),
                ('subcase','i4',1),

                ('LSDVMN','i4',1), # Load set number
                ('UNDEF(2)','i4',2), # Undefined
                ('LOADSET','i4',1), # Load set number or zero or random code identification number
                ('FCODE','i4',1), # Format code
                ('NUMWDE(C)','i4',1), # Number of words per entry in DATA record
                ('SCODE(C)','i4',1), # Stress/strain code
                ('UNDEF(11)','i4',11), # Undefined
                ('THERMAL(C)','i4',1), # =1 for heat transfer and 0 otherwise
                ('UNDEF(27)','i4',27), # Undefined
                ('TITLE(32)','S1',32*4), # Title
                ('SUBTITL(32)','S1',32*4), # Subtitle
                ('LABEL(32)','S1',32*4), # Label
                ('10','i4',1),

                # Record 3 -- Data
                ('11','i4',1),('KEY1','i4',1),('12','i4',1),
                ('13','i4',1),('KEY2','i4',1),('14','i4',1),
                ('15','i4',1),('KEY3','i4',1),('16','i4',1),
                ('17','i4',1),('KEY4','i4',1),('18','i4',1),
                ('19','i4',1),
                ('EKEY','i4',1), #Element key = 10*EID+Device Code. EID = (Element key)//10
                ('FD1','f4',1),
                ('EX1','f4',1),
                ('EY1','f4',1),
                ('EXY1','f4',1),
                ('EA1','f4',1),
                ('EMJRP1','f4',1),
                ('EMNRP1','f4',1),
                ('EMAX1','f4',1),
                ('FD2','f4',1),
                ('EX2','f4',1),
                ('EY2','f4',1),
                ('EXY2','f4',1),
                ('EA2','f4',1),
                ('EMJRP2','f4',1),
                ('EMNRP2','f4',1),
                ('EMAX2','f4',1),
                ('20','i4',1)]

                nparr = np.fromfile(f,dtype=OES)


            if f.tell() == filesize:
                break
4

0 回答 0