与IDL方法相比,使用Python中的解压缩读取二进制文件

时间:2018-09-18 12:02:47

标签: python numpy binary idl-programming-language

我有一个IDL过程读取二进制文件,然后尝试将其转换为Python例程。 IDL代码如下:

a = uint(0)
b = float(0)
c = float(0)
d = float(0)
e = float(0)
x=dblarr(nptx)
y=dblarr(npty)
z=dblarr(nptz)
openr,11,name_file_data,/f77_unformatted
readu,11,a
readu,11,b,c,d,e
readu,11,x
readu,11,y
readu,11,z

它完美地工作。所以我在python中写了同样的东西,但找不到相同的结果(即使'a'的值也不同)。这是我的代码:

x=np.zeros(nptx,float)
y=np.zeros(npty,float)
z=np.zeros(nptz,float)
with open(name_file_data, "rb") as fb:
    a, = struct.unpack("I", fb.read(4))
    b,c,d,e = struct.unpack("ffff", fb.read(16))
    x[:] = struct.unpack(str(nptx)+"d", fb.read(nptx*8))[:]
    y[:] = struct.unpack(str(npty)+"d", fb.read(npty*8))[:]
    z[:] = struct.unpack(str(nptz)+"d", fb.read(nptz*8))[:]

希望它会帮助任何人回答我。

更新:如答案中所建议,我现在正在尝试模块“ FortranFile”,但不确定我是否了解其用法。

from scipy.io import FortranFile
f=FortranFile(name_file_data, 'r')
a=f.read_record('H')
b=f.read_record('f','f','f','f')

但是,我得到的不是数组'a'的整数,而是:array([0,0],dtype = uint16)。

我对于'b'遇到以下错误:获得的大小(1107201884)不是给定dtype(16)的倍数

1 个答案:

答案 0 :(得分:1)

根据a table of IDL data typesUINT(0)创建一个 16位整数(即两个字节)。在Python struct module中,I format character表示4字节整数,而H表示16位无符号整数。

尝试将将a拆包的行更改为

    a, = struct.unpack("H", fb.read(2))

不幸的是,这可能无法解决问题。您可以将/f77_unformattedopenr一起使用,这意味着文件不仅仅包含变量的原始字节。 (有关/f77_unformatted的更多信息,请参见documentation of the OPENR command。)

您可以尝试使用scipy.io.FortranFile来读取文件,但是没有保证的文件。未格式化的Fortran文件的二进制布局取决于编译器。