如何在Python中读取Fortran生成的.j03格式二进制数据文件?
读取IFORT生成的无格式Fortran .j03二进制文件的Python方案
核心背景
你面对的是IFORT编译器生成的标准无格式Fortran二进制文件,核心特征:
- 记录式存储,每个记录首尾各加4字节小端整数(标记记录的字节长度)
- 数据单元为4字节小端单精度浮点
以下是可直接运行的读取方案,完美匹配你提供的示例数据结构:
实现代码
import numpy as np def read_j03(file_path): with open(file_path, 'rb') as f: # 解析开头的文本记录(variables和zone元数据) # 读取记录长度(4字节小端整数) rec_len = np.fromfile(f, dtype=np.int32, count=1)[0] # 读取ASCII格式的文本内容 text_block = f.read(rec_len).decode('ascii').strip() # 跳过记录末尾的长度标记 f.seek(f.tell() + 4) # 提取元数据信息 var_line, zone_line = text_block.split('\n') # 从zone行获取网格尺寸 i_size = int(zone_line.split('i=')[1].split(',')[0].strip()) j_size = int(zone_line.split('j=')[1].split(',')[0].strip()) # 统计变量数量 var_count = len([v for v in var_line.split('"') if v.strip()]) # 读取数据记录 data_rec_len = np.fromfile(f, dtype=np.int32, count=1)[0] # 按小端单精度浮点读取所有数据 raw_data = np.fromfile(f, dtype='<f4', count=i_size * j_size * var_count) # 跳过记录末尾的长度标记 f.seek(f.tell() + 4) # 重塑为网格结构:(j行, i列, 变量数) grid_data = raw_data.reshape(j_size, i_size, var_count) return var_line, zone_line, grid_data # 测试读取示例 if __name__ == '__main__': vars_info, zone_info, data = read_j03("your_file.j03") # 打印验证前6行数据(对应示例中固定z值的行) print(vars_info) print(zone_info) for idx in range(6): print(' '.join([f'{val:20.12f}' for val in data[0, idx, :]]))
关键细节说明
- 记录处理逻辑:必须严格遵循「读记录长度→读记录内容→跳末尾标记」的流程,否则会导致数据偏移,读取完全错误。
- 字节序指定:用
'<f4'明确指定小端单精度浮点,完全匹配文件的字节序要求。 - 数据重塑:根据zone行的
i=128和j=85,将一维数组重塑为(85,128,9)的三维数组,方便按网格点直接访问对应变量值。 - 文本解析:开头的记录是ASCII编码的元数据,直接解码即可提取变量名和网格信息,无需额外转码处理。
运行代码后,输出的前几行数据会和你提供的示例完全一致。
内容的提问来源于stack exchange,提问作者gettingmathy
相关产品推荐
相关产品推荐

