[英]Reading Unformatted Binary file: Unexpected output - Fortran90
前言:我需要弄清楚二進制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(或其他任何地方,真正的)背景。 請參閱英特爾的以下文檔,該文檔對不同的訪問模式給出了很好的解釋:
簡而言之,它具有描述每個條目中數據的額外數據(標題)。
此外,我不能使用ACCESS = stream由於機器老舊而不支持,所以我得出結論,上面是唯一可能找出文件結構。 任何指導都將是一個很大的幫助!
如果你不能使用stream
,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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.