在 Fortran 90 中读取二进制网格文件
Reading in a binary grid file in Fortran 90
我在尝试读取之前写入另一个程序的二进制文件时遇到问题。我已经能够打开它并将其读入一个数组而没有编译错误,但是,该数组未填充(全为 0)。任何建议或想法都会很棒。这是我正在使用的 open/read 语句:
allocate(dummy(imax,jmax))
open(unit=io, file=trim(input), form='binary', access='stream', &
iostat=ioer, status='old', action='READWRITE')
if(ioer/=0) then
print*, 'Cannot open file'
else
print*,'success opening file'
end if
read(unit=io, fmt=*, iostat=ioer) dummy
j=0
k=0
size: do j=1, imax
do k=1, jmax
if(dummy(j,k) > 0.) print*,dummy(j,k)
end do
end do size
如果您需要更多信息,请告诉我。
文件最初是这样写的:
out_file = trim(output_dir)//'SEVIRI_FRP_.08deg_'//trim(season)//'.bin'
print*, out_file
print*, i_max,' i_max,',j_max,' j_max'
open (io, file = out_file, access = 'direct', status = 'replace', recl = i_max*j_max*4)
write(io, rec = 1) sev_frp
write(io, rec = 2) count_sev_frp
write(io, rec = 3) sum_sev_frp
check: do n=1, i_max
inna: do m=1, j_max
!if (sev_frp(n,m) > 0) print*, count_sev_frp(n,m)
end do inna
end do check
print*,'n-',n,'m-',m
close(io)
首先,据我所知,form
有两个可能的值:"FORMATTED"
或 "UNFORMATTED"
。
其次,要阅读,您应该使用与您用来写入文件的 open
语句对称的 open
,除非您确切地知道自己在做什么。我建议阅读时打开:
open(unit=io, file=trim(input), access='direct', &
iostat=ioer, status='old', action='READ', recl = i_max*j_max*4)
这对应于您用来保存文件的打开语句。
作为,您的文件写入方式与读取方式不匹配。
外部文件可以通过以下三种访问方法之一连接:顺序;直接的;溪流。此外,连接可以是格式化的或未格式化的。
当打开文件进行写入时,它使用直接访问方法和未格式化的记录。记录未格式化,因为这是默认设置(缺少 form=
说明符)。
当您打开文件进行阅读时,您使用 form="binary"
的非标准扩展名和流访问。这可能没有什么问题,但确实需要小心。
但是,对于 read
语句,您使用的是格式化(列表导向)输入。这是不允许的。
上一个答案中建议的方式,使用类似的访问方法和记录长度将需要进一步更改代码。 [您还需要以某种方式设置记录长度的值。]
您不仅需要删除格式以匹配写入的未格式化记录,而且您还需要使用 rec=
说明符来访问文件的记录。
最后,如果您使用 iostat=
说明符,您确实应该检查结果值。
我在尝试读取之前写入另一个程序的二进制文件时遇到问题。我已经能够打开它并将其读入一个数组而没有编译错误,但是,该数组未填充(全为 0)。任何建议或想法都会很棒。这是我正在使用的 open/read 语句:
allocate(dummy(imax,jmax))
open(unit=io, file=trim(input), form='binary', access='stream', &
iostat=ioer, status='old', action='READWRITE')
if(ioer/=0) then
print*, 'Cannot open file'
else
print*,'success opening file'
end if
read(unit=io, fmt=*, iostat=ioer) dummy
j=0
k=0
size: do j=1, imax
do k=1, jmax
if(dummy(j,k) > 0.) print*,dummy(j,k)
end do
end do size
如果您需要更多信息,请告诉我。
文件最初是这样写的:
out_file = trim(output_dir)//'SEVIRI_FRP_.08deg_'//trim(season)//'.bin'
print*, out_file
print*, i_max,' i_max,',j_max,' j_max'
open (io, file = out_file, access = 'direct', status = 'replace', recl = i_max*j_max*4)
write(io, rec = 1) sev_frp
write(io, rec = 2) count_sev_frp
write(io, rec = 3) sum_sev_frp
check: do n=1, i_max
inna: do m=1, j_max
!if (sev_frp(n,m) > 0) print*, count_sev_frp(n,m)
end do inna
end do check
print*,'n-',n,'m-',m
close(io)
首先,据我所知,form
有两个可能的值:"FORMATTED"
或 "UNFORMATTED"
。
其次,要阅读,您应该使用与您用来写入文件的 open
语句对称的 open
,除非您确切地知道自己在做什么。我建议阅读时打开:
open(unit=io, file=trim(input), access='direct', &
iostat=ioer, status='old', action='READ', recl = i_max*j_max*4)
这对应于您用来保存文件的打开语句。
作为
外部文件可以通过以下三种访问方法之一连接:顺序;直接的;溪流。此外,连接可以是格式化的或未格式化的。
当打开文件进行写入时,它使用直接访问方法和未格式化的记录。记录未格式化,因为这是默认设置(缺少 form=
说明符)。
当您打开文件进行阅读时,您使用 form="binary"
的非标准扩展名和流访问。这可能没有什么问题,但确实需要小心。
但是,对于 read
语句,您使用的是格式化(列表导向)输入。这是不允许的。
上一个答案中建议的方式,使用类似的访问方法和记录长度将需要进一步更改代码。 [您还需要以某种方式设置记录长度的值。]
您不仅需要删除格式以匹配写入的未格式化记录,而且您还需要使用 rec=
说明符来访问文件的记录。
最后,如果您使用 iostat=
说明符,您确实应该检查结果值。