File io 在Fortran90+中使用可分配组件对数据类型进行二进制读/写;
保存变量File io 在Fortran90+中使用可分配组件对数据类型进行二进制读/写;,file-io,fortran,binaryfiles,binary-data,File Io,Fortran,Binaryfiles,Binary Data,保存变量save的二进制快照的最佳方法是什么,该变量由下面的sample数据类型组成 program save_it type core integer, dimension(8) :: indx end type core type sample integer :: a real*8, dimension(:), allocatable :: b type(core), dimension(:), allocatable
save
的二进制快照的最佳方法是什么,该变量由下面的sample
数据类型组成
program save_it
type core
integer, dimension(8) :: indx
end type core
type sample
integer :: a
real*8, dimension(:), allocatable :: b
type(core), dimension(:), allocatable :: c
end type sample
! here it comes
type(sample) :: save
! here we allocate all componenets of variable "save"
!.
!.
! Now, how to write/read variable "save" to/from external file?
end program save_it
>在C++中有相当直接的二进制输入/输出流,但我不知道如何在FORTRAN 90+< /P> > P >如果FORTRAN90+意味着你对FORTRAN 2003感到满意,那么就有了用户定义的派生类型IO的选项。这允许您在write语句中包装分配所需的额外簿记。我将把示例代码放在底部 如果您不想使用此功能,这可能是因为您没有支持它的编译器(我已经用ifort 14进行了测试),那么您可以很容易地模拟簿记 关键的部分只是发送和读取大小,并在读取之前分配变量 守则:
module types
type core
integer, dimension(8) :: indx
end type core
type sample
integer :: a
real*8, dimension(:), allocatable :: b
type(core), dimension(:), allocatable :: c
contains
procedure write_sample
procedure read_sample
generic :: write(unformatted) => write_sample
generic :: read(unformatted) => read_sample
end type sample
contains
! Unformatted writing for the sample derived type
subroutine write_sample(dtv, unit, iostat, iomsg)
class(sample), intent(in) :: dtv
integer, intent(in) :: unit
integer, intent(out) :: iostat
character(*), intent(inout) :: iomsg
integer i
! Write a record giving sizes for the allocation
write(unit, iostat=iostat, iomsg=iomsg) SIZE(dtv%b), SIZE(dtv%c)
write(unit, iostat=iostat, iomsg=iomsg) dtv%a, dtv%b, &
(dtv%c(i)%indx, i=1,SIZE(dtv%c))
end subroutine write_sample
! Unformatted reading for the sample derived type
subroutine read_sample(dtv, unit, iostat, iomsg)
class(sample), intent(inout) :: dtv
integer, intent(in) :: unit
integer, intent(out) :: iostat
character(*), intent(inout) :: iomsg
integer i
integer sizeb, sizec
! We first have a record telling us the sizes of components
read(unit, iostat=iostat, iomsg=iomsg) sizeb, sizec
! So we do the allocation
allocate(dtv%b(sizeb), dtv%c(sizec))
! And then finally the reading.
read(unit, iostat=iostat, iomsg=iomsg) dtv%a, dtv%b, &
(dtv%c(i)%indx, i=1,SIZE(dtv%c))
end subroutine read_sample
end module types
program save_it
use types
implicit none
integer i, unit_in, unit_out
! here it comes
type(sample) :: save
type(sample) :: save_test
! Define some values - using ifort don't forget to set the compile flag
save%a = 14
save%b = [(i*1., i=1, 10)]
save%c = [core([(i, i=1,8)]), core([(i, i=11, 18)])]
! Write out the derived type
open(newunit=unit_out, file='serial', form='unformatted', &
status='replace', action='write')
write(unit_out) save
close(unit_out)
! Read in the derived type to a new one
open(newunit=unit_in, file='serial', form='unformatted', &
status='old', action='read')
read(unit_in) save_test
close(unit_in)
! Test, if we want to be certain
end program save_it
要使其健壮,当然还有很多工作要做。非常有洞察力的代码和很棒的想法!谢谢注意,子输入/输出语句始终被视为非前进语句-write_sample和read_sample过程都只在主程序中由父write和read语句创建的单个记录中写入和读取数据。@这是一个很好的观点,谢谢。也许在我的程序评论中,我应该说“chunk”而不是“record”?或者有一个加载更少/更正确的术语?@francescalus你在用什么编译器?这不适用于gfortran 6.3.0(据我所知,MinGW的最新可用版本)。我得到:
generic::write(未格式化)=>write\u sample
,错误:在(1)处应为“=>”。如果我删除,(未格式化)
,我会得到:写入(unit_out)保存
,错误:位于(1)的数据传输元素不能有可分配组件,除非它由定义的输入/输出过程处理
@JeffIrwin,我使用了ifort(14,如果我在答案中的注释是正确的,则不在后面测试)。据我所知,您需要gfortran 7+来支持已定义的I/O。