python unpack_Python二进制文件读写

小量最近用PySCF计算Hartree-Fock轨道传递给自己的程序使用,为了保证精度和节省硬盘空间,使用二进制文件来传递数据。本文简单小结一下Python的二进制文件的读写。

在Python中实现二进制文件的读写需要导入struct模块,对数据进行打包处理再写入文件。以下直接举一个简短的程序示例:

  1   #!/usr/bin/python

  2   import struct

  3   f = open('test.bin', 'w+b')

  4   a0 = 1

  5   a1 = 2

  6   data = struct.pack('2i', a0, a1)

  7   f.write(data)

  8   f.seek(0)

  9   data2 = f.read()

 10   (a, b) = struct.unpack('ii', data2)

 11   print a, b

第3行,打开文件时,模式需要添加'b'模式,表示二进制模式。注意,以读写模式打开时,不能写rw,应该写r+或w+模式。

第6行,将数据转化成二进制并进行打包。其通用格式为struct.pack(fmt,v1,v2,...)。由于python中数据不需要声明类型,因此需要在打包时指明数据类型,才能确定数据的字节数。例如本例中2i表示将两个整型数进行打包。各种数据类型所用的符号以及所占的字节数在Python的官方手册中有列表:

0152f163693ac172fa702acbfa692a56.png

第7行,将数据写入文件。

第10行,将读出的数据解包,并根据数据类型转化为普通格式。注意,解包出来的数据会构成一个元组,因此,如果只有一个数据,要写成a,或者(a,)。

笔者遇到一个问题,始终不知道是何原因,如果有小伙伴知道,请留言告知。笔者尝试将一个整数和一个浮点数打包,格式为'id',按理来说,i占4位,d占8位,得到的数据应该是12位,但观察到的是16位。后来笔者又用做了一系列测试,结果如下:

>>> struct.calcsize('id')

16

>>> struct.calcsize('iid')

16

>>> struct.calcsize('iiid')

24

>>> struct.calcsize('iiiid')

24

>>> struct.calcsize('iiiiid')

32

>>> struct.calcsize('iiiiiid')

32

当i的个数为奇数时,始终会多计算4位。不知当中有何玄机。为避免这个问题,建议大家将不同类型的数据分批打包,依次写入文件。例如第一次单独写一个i类型数据,第二次单独写入一个d类型数据,得到的大小就是12。

最后,顺便提一下Fortran中二进制文件的读写。在彭国伦的教材中提到,文件的格式有两种:formatted和unformatted,其实还有第三种格式:binary。如果用Fortran程序读取上述Python代码生成的二进制文件,使用unformatted时,无法正常读出,需要写成binary格式:

program main

implicit none

integer*4 a,b

open(unit=10,file='test.bin',form='binary')

read(10) a,b

write(*,*) a,b

end

注意在Python中是以4位存储的整数,因此在Fortran中要声明4位的整数来读取。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值