前言:我需要弄清楚二进制grid_data_file的结构.从Fortran例程中我发现第一条记录由57个字节组成,并按以下顺序包含信息.
No. of the file :: integer*4
File name :: char*16
file status :: char*3 (i.e. new, old, tmp)
.... so forth (rest is clear from write statement in the program)
现在进行测试我写了一个简单的程序如下:(我没有包含所有参数)
Program testIO
implicit none
integer :: x, nclat, nclon
character :: y, z
real :: lat_gap, lon_gap, north_lat, west_lat
integer :: gridtype
open(11, file='filename', access='direct', form='unformatted', recl='200')
read(11, rec=1) x,y,z,lat_gap,lon_gap, north_lat,west_lat, nclat, nclon, gridtyp
write(*,*) x,y,z,lat_gap,lon_gap, north_lat,west_lat, nclat, nclon, gridtyp
close(11)
END
令我惊讶的是,当我将声明部分更改为
integer*4 :: x, nclat, nclon
character*16 :: y
character*3 :: z
real*4 :: lat_gap, lon_gap, north_lat, west_lat
integer*2 :: gridtype
它给了我一些正确的信息,尽管不是全部!我无法理解这一点.如果有人解释这种现象,它将有助于我提高我的Fortran知识.
此外,我不能使用ACCESS = stream由于机器老旧而不支持,所以我得出结论,上面是唯一可能找出文件结构.
最佳答案 从您的回复和其他人的评论中,我认为您的问题可能是对Fortran“记录”的误解:
你说你有一个二进制文件,其中每个条目(你说的记录,但稍后更多)是57个字节.
问题是Fortran I / O中的“记录”并不是您所期望的来自C(或其他任何地方,真正的)背景.请参阅英特尔的以下文档,该文档对不同的访问模式给出了很好的解释:
简而言之,它具有描述每个条目中数据的额外数据(标题).
Moreover, I can’t use ACCESS=stream due to machine being old and not supported, so I conclude that above is the only possibility to figure out the file structure. Any guidance would be a big help!
如果你不能使用流,AFAIK真的没有简单而无痛的方法来读取没有记录信息的二进制文件.
需要C编译器的可能解决方案是在您从Fortran调用的C函数中执行IO,“最小”示例:
main.f90时:
program main
integer, parameter :: dp = selected_real_kind(15)
character(len=*), parameter :: filename = 'test.bin'
real(dp) :: val
call read_bin(filename, val)
print*, 'Read: ', val
end program
read.c:
#include <string.h>
#include <stdio.h>
void read_bin_(const char *fname, double *ret, unsigned int len)
{
char buf[256];
printf("len = %d\n", len);
strncpy(buf, fname, len);
buf[len] = '\0'; // fortran strings are not 0-terminated
FILE* fh = fopen(buf, "rb");
fread(ret, sizeof(double), 1, fh);
fclose(fh);
}
请注意,由于Fortran处理字符串的方式,最终需要一个额外的参数和一些字符串操作,这与C不同.
为write.c:
#include <stdio.h>
int main() {
double d = 1.234;
FILE* fh = fopen("test.bin", "wb");
fwrite(&d, sizeof(double), 1, fh);
fclose(fh);
}
编制说明:
gcc -o write write.c
gcc -c -g read.c
gfortran -g -o readbin main.f90 read.o
使用./write创建二进制文件,然后查看Fortran代码如何使用./readbin读取它.
这可以针对不同的数据类型进行扩展,以基本上模拟access = stream.最后,如果你可以重新编译原始的Fortran代码以不同的方式输出数据文件,这将是最简单的解决方案,因为这是一个粗暴的黑客.
最后,获取未知数据格式的提示:工具od是您的朋友,请查看其联机帮助页.它可以直接将二进制represantations转换为各种不同的本机数据类型.试试上面的例子(z在右栏中添加了字符表示,在这里不是很有用,一般是的):
od -t fDz test.bin