简体   繁体   English

在Python2中编写二进制访问流数据以在Fortran中读取

[英]Writing binary access stream data in Python2 for reading in Fortran

I don't have working knowledge of Fortran, nor am I an advanced user of Python(2), so please bear that in mind and please be understanding! 我没有Fortran的工作知识,也不是Python(2)的高级用户,所以请记住这一点,并请谅解!

I'm trying to write some data into a binary file with Python2 (opened an empty binary file with "wb"), which has to be opened as an "unformatted" file in Fortran (a .f90 file). 我正在尝试使用Python2将一些数据写入二进制文件(使用“ wb”打开一个空的二进制文件),该文件必须作为Fortran中的“未格式化”文件(.f90文件)打开。 The thing is, such a Python-generated binary file can be read (in Fortran) if I have, when opening the file in Fortran, 事实是,如果在Fortran中打开该文件时,可以读取(在Fortran中)这样的Python生成的二进制文件,

"form='unformatted'", and "access='stream'". “ form ='unformatted'”和“ access ='stream'”。

I am hoping to write a binary file in Python 2 such that I do not need "access='stream'". 我希望在Python 2中编写一个二进制文件,这样不需要“ access ='stream'”。 I am using this binary file in conjunction with a massive nonpublic code in Fortran (which I did not develop), and would like to not touch the source code at all. 我将这个二进制文件与Fortran中大量的非公开代码(我没有开发过)结合使用,并且希望完全不涉及源代码。 I only made changes as a test for myself. 我只是进行更改作为对自己的测试。

If I do not use "access='stream'", then I just get nonsensical values that are output. 如果我不使用“ access ='stream'”,那么我只会得到输出的无意义值。

I was using the below before (byteswap() for changing endianness) to write the binary file, to no avail. 我以前使用下面的方法(用于更改字节序的byteswap())将二进制文件写入,但无济于事。

dxidxup = 1/dxm
dxidxup = np.array(dxidxup,dtype='<f4')
dxidxup_write = dxidxup.byteswap()
dxidxup_write.tofile(new_mesh)

I also tried to use np.ascontiguousarray and np.asfortranarray to write the data to the binary file, but it did not work either. 我也尝试使用np.ascontiguousarray和np.asfortranarray将数据写入二进制文件,但是它也不起作用。

dxidxup = 1/dxm
dxidxup = np.array(dxidxup)
dxidxup = np.ascontiguousarray(dxidxup,dtype='<f4')
dxidxup_write = dxidxup.byteswap()
dxidxup_write.tofile(new_mesh)

I have tried struct.pack too, as per this link . 根据此链接 ,我也尝试过struct.pack。 I am not sure what other avenue to best pursue... I appreciate thoughts/inputs! 我不确定还有其他最佳途径...我感谢您的想法/投入!

I hope that all made sense.. 我希望一切都有意义。

Well, this may be quite tricky. 好吧,这可能很棘手。 Binary input/output particularly depends on the chosen Fortran compiler and limits portability. 二进制输入/输出特别取决于所选的Fortran编译器并限制了可移植性。

In case of UNFORMATED SEQUENTIAL or DIREC input/output Fortran causes logical records to be read or written. 如果是未格式化的序列或直接输入/输出,则Fortran会导致读取或写入逻辑记录。 Fortran inserts an integer byte count at the beginning and end of data written. Fortran在写入的数据的开头和结尾插入一个整数字节计数。

Here is an example with two records of length two and three that works with fort77 . 这是一个具有长度为2和3的两个记录的示例,该记录与fort77一起fort77 Python code for generating the binary: 用于生成二进制文件的Python代码:

import struct
fh = open('two_records.bin', 'wb')
fh.write(struct.pack('l',2)) # Compiler dependent
fh.write('ab')
fh.write(struct.pack('l',2))
fh.write(struct.pack('l',3))
fh.write('cde')
fh.write(struct.pack('l',3))
fh.close()

Fortran 77 Code that reads the file: Fortran 77读取文件的代码:

      character*2 a
      character*3 b
      open(12, FILE='two_records.bin', FORM='unformatted')
      read(12) a
      read(12) b
      close(12)
      end

If you prefer any other compiler you have to figure out if the byte count is int or longint . 如果您更喜欢其他编译器,则必须弄清楚字节数是int还是longint In contrast to f2c , by default gfortran uses int32 which may be changed by setting -frecord-marker=8 . f2c ,默认情况下, gfortran使用int32 ,可以通过设置-frecord-marker=8来更改它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM