簡體   English   中英

讀取未格式化的二進制文件:意外的輸出 - Fortran90

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM