Python未格式化保存

时间:2016-08-26 15:05:27

标签: python io binary fortran read-write

我正在使用python为程序创建输入。该程序将未格式化的二进制文件作为输入。如果我使用fortran,我会用

创建这个文件
   open (10,file=outfile,status='unknown',form='unformatted')
   write(10) int1,int2,int3,int4,list0
   write (10) list1
   write (10) list2
   write (10) list3
   write (10) list4
   close (10)

有没有办法在python中创建相同类型的文件?我的第一个猜测是在fortran中创建一个子程序,它可以保存文件给出一些输入,然后使用f2py在我的python代码中实现它,但我真的不知道怎么会这样做。 我写入文件的列表非常大,确切的结构非常重要。这意味着Writing Fortran unformatted files with Python之类的答案似乎并不令人满意,因为他们没有充分处理文件/字节序中的标题等等。

在我的python代码中,a有一个2维数组,每行包含x,y,z坐标和粒子质量。这些数据需要在许多文件中分开。

对于粒子加载,文件的结构是:

BLOCK-1 - 正文长度为48个字节:

  nparticles_this_file   -    integer*4   (nlist)
  nparticles_total       -    integer*8
  number of this file    -    integer*4
  total number of files -     integer*4
  Not used              -   7*integer*4

BLOCK-2

 A list of nlist  x-coordinates   (real*8)

(x坐标以周期框大小0< = x< 1)为单位

BLOCK-3

 A list of nlist  y-coordinates   (real*8)

(y坐标以周期框大小0< = y< 1)为单位

BLOCK-4

 A list of nlist  z-coordinates   (real*8)

(z坐标以周期框大小0< = z< 1为单位)

BLOCK-5

A list of nlist particle masses  (real*4)

以周期性体积中的总质量为单位

1 个答案:

答案 0 :(得分:1)

以下代码应该是您尝试做的一个很好的起点。您的数据结构并不像我期望的那样复杂。 我写了一个小函数来写在列表上,因为它非常重复。最值得注意的是fortran无格式文件会记录每条记录的大小以及记录(记录前后)。这有助于fortran自己在以后读取文件时检查基本错误。使用fortran流文件将使您无需编写记录大小。

import numpy as np

def writeBloc(dList, fId):
    """Write a single list of data values ad float 64 or fortran real*8"""
    np.array([len(dList)*8],np.int32).tofile(fId) # record size
    np.array([dList],np.float64).tofile(fId)
    np.array([len(dList)*8],np.int32).tofile(fId) # record size


int1,int2,int3,int4 = 4, 100, 25, 25
#
f = open("python.dat", "wb")
# Block 1
np.array([48],np.int32).tofile(f) # record size
np.array([int1],np.int32).tofile(f)
np.array([int2],np.int64).tofile(f)
np.array([int3],np.int32).tofile(f)
np.array([int4],np.int32).tofile(f)
np.zeros((7),np.int32).tofile(f) # list0
np.array([48],np.int32).tofile(f) # record size
#
list1=[10.0, 11.0, 12.0, 13.0]
list2=[20.0, 21.0, 22.0, 23.0]
list3=[30.0, 31.0, 32.0, 33.0]
list4=[40.0, 41.0, 42.0, 43.0]
# data
writeBloc(list1, f) # Block 1
writeBloc(list2, f) # Block 2
writeBloc(list3, f) # Block 3
writeBloc(list4, f) # Block 4
f.close()