gpt4 book ai didi

io - 读取未格式化的二进制文件: Unexpected output - Fortran90

转载 作者:行者123 更新时间:2023-12-03 02:54:07 25 4
gpt4 key购买 nike

前言:我需要弄清楚二进制 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(或其他任何地方,实际上)背景。请参阅 Intel 的以下文档,其中很好地解释了不同的访问模式:

简而言之,它具有描述每个条目中的数据的额外数据( header )。

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!

如果你不能使用stream,据我所知,确实没有简单、轻松的方法来读取没有记录信息的二进制文件。

需要 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

读取.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 不同,最后需要一个额外的参数和一些字符串操作。

写.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 代码以不同方式输出数据文件,这将是最简单的解决方案,因为这几乎是一种粗略的 hack。

最后,关于了解未知数据格式的提示:od 工具是您的 friend ,请查看其联机帮助页。它可以直接将二进制表示转换为各种不同的 native 数据类型。尝试使用上面的示例(z 在右侧列中添加字符表示,这里不是很有用,一般来说是有用的):

od -t fDz test.bin

关于io - 读取未格式化的二进制文件: Unexpected output - Fortran90,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25037247/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com