Python 未格式化保存

Python unformatted save

我正在使用 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 之类的答案似乎并不令人满意,因为它们没有充分处理 file/endianess 中的 headers 等等。

在我的 python 代码中有一个二维数组,每一行包含 x、y、z 坐标和粒子的质量。此数据需要拆分为多个文件。

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

BLOCK-1 - body 是 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-coordinate以周期框大小为单位0<=x<1)

BLOCK-3

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

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

BLOCK-4

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

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

第 5 块

A list of nlist particle masses  (real*4)

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

像下面这样的代码应该是您尝试执行的操作的良好起点。您的数据结构并不像我从您的解释中预期的那样复杂。 我写了一个小函数来写在列表上,因为它非常重复。需要注意的最重要的一点是,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()