我正在尝试使用BIG-ENDIAN格式读取未格式化的文件。如何读取此文件并将其正确输出到.dat文件中?
我在Fortran不太熟悉代码。在许多论坛上发布后,我得到了一些似乎不完整的代码。
module modbin
type rectype
character(len=8)::key
integer::data_count
character(len=4)::data_type
logical::is_int
integer, allocatable:: idata(:)
real(kind=8), allocatable::rdata(:)
end type
contains
subroutine rec_read(in_file, out_rec)
integer, intent(in):: in_file
type (rectype), intent(inout):: out_rec
!
! You need to play around with this figure. It may not be
! entirely accurate - 1000 seems to work, 1024 does not
integer, parameter:: bsize = 1000
integer:: bb, ii, iimax
! read the header
out_rec%data_count = 0
out_rec%data_type = ' '
read(in_file, end = 20) out_rec%key, out_rec%data_count,
out_rec%data_type
! what type is it?
select case (out_rec%data_type)
case ('INTE')
out_rec%is_int = .true.
allocate(out_rec%idata(out_rec%data_count))
case ('DOUB')
out_rec%is_int = .false.
allocate(out_rec%rdata(out_rec%data_count))
end select
! read the data in blocks of bsize
bb = 1
do while (bb .lt. out_rec%data_count)
iimax = bb + bsize - 1
if (iimax .gt. out_rec%data_count) iimax = out_rec%data_count
if (out_rec%is_int) then
read(in_file) (out_rec%idata(ii), ii = bb, iimax)
else
read(in_file) (out_rec%rdata(ii), ii = bb, iimax)
end if
bb = iimax + 1
end do
20 continue
end subroutine rec_read
subroutine rec_print(in_recnum, in_rec)
integer, intent(in):: in_recnum
type (rectype), intent(in):: in_rec
print *, in_recnum, in_rec%key, in_rec%data_count, in_rec%data_type
! print out data
open(unit=12, file='reader.data' , status='old')
write(*,'(i5)')GEOMETRY
close(12)
end subroutine rec_print
end module modbin
program main
use modbin
integer, parameter:: infile=11
! fixed size for now - should really be allocatable
integer, parameter:: rrmax = 500
type (rectype):: rec(rrmax)
integer:: rr, rlast
open(unit=infile, file='TEST1603.SLN0001', form='UNFORMATTED',
status='OLD', convert='BIG_ENDIAN')
rlast = 0
do rr = 1, rrmax
call rec_read(infile, rec(rr))
if (rec(rr)%data_type .eq. ' ') exit
rlast = rr
call rec_print(rr, rec(rr))
end do
close(infile)
end program main
我希望前几行数据的输出为
答案 0 :(得分:0)
我制作了您的程序的稍作修改的版本,该程序读取二进制文件并生成符合格式文件的可读文件“ reader.data”。在标准输出上也是如此。
module modbin
implicit none
type rectype
character(len=8)::key
integer::data_count
character(len=4)::data_type
logical::is_int
integer, allocatable:: idata(:)
real(kind=8), allocatable::rdata(:)
end type
contains
subroutine rec_read(in_file, out_rec)
integer, intent(in):: in_file
type (rectype), intent(inout):: out_rec
!
! You need to play around with this figure. It may not be
! entirely accurate - 1000 seems to work, 1024 does not
integer, parameter:: bsize = 1000
integer:: bb, ii, iimax
! read the header
out_rec%data_count = 0
out_rec%data_type = ' '
read(in_file, end = 20) out_rec%key, out_rec%data_count, out_rec%data_type
! what type is it?
select case (out_rec%data_type)
case ('INTE')
out_rec%is_int = .true.
allocate(out_rec%idata(out_rec%data_count))
case ('DOUB')
out_rec%is_int = .false.
allocate(out_rec%rdata(out_rec%data_count))
end select
! read the data in blocks of bsize
bb = 0
do while (bb .lt. out_rec%data_count)
iimax = bb + bsize
if (iimax .gt. out_rec%data_count) iimax = out_rec%data_count
if (out_rec%is_int) then
read(in_file) (out_rec%idata(ii), ii = bb+1, iimax)
else
read(in_file) (out_rec%rdata(ii), ii = bb+1, iimax)
end if
bb = iimax
end do
20 continue
end subroutine rec_read
subroutine rec_print(outfile, in_rec)
integer, intent(in):: outfile
type (rectype), intent(in):: in_rec
integer, parameter:: bsize = 1000
integer bb,iimax,ii
write(outfile,'(" ''",a,"''",i12," ''",a,"''")') in_rec%key,in_rec%data_count,in_rec%data_type
print '(" ''",a,"''",i12," ''",a,"''")', in_rec%key, in_rec%data_count, in_rec%data_type
! print out data
bb = 0
do while (bb .lt. in_rec%data_count)
iimax = bb + bsize
if (iimax .gt. in_rec%data_count) iimax = in_rec%data_count
if (in_rec%is_int) then
write(outfile,'(6i12)') (in_rec%idata(ii), ii=bb+1,iimax)
print '(6i12)', (in_rec%idata(ii), ii=bb+1,iimax)
else
write(outfile,'(3d23.14)') (in_rec%rdata(ii), ii=bb+1,iimax)
print '(3d23.14)', (in_rec%rdata(ii), ii=bb+1,iimax)
endif
bb = iimax
enddo
end subroutine rec_print
end module modbin
program main
use modbin
implicit none
integer, parameter:: infile = 11
integer, parameter:: outfile = 12
! fixed size for now - should really be allocatable
integer, parameter:: rrmax = 500
type (rectype):: rec(rrmax)
integer:: rr, rlast, k(10),i
character*8 text1
character*4 text2
open(unit=outfile, file='reader.data')
open(unit=infile, file='TEST1603.SLN0001', form='UNFORMATTED', status='OLD', convert='BIG_ENDIAN')
read(unit=infile) text1,i,text2
write(unit=outfile,fmt='(" ''",a,"''",i12," ''",a,"''")') text1,i,text2
print '(" ''",a,"''",i12," ''",a,"''")',text1,i,text2
read(unit=infile) k
write(unit=outfile,fmt='(6i12)') k
print '(6i12)',k
rlast = 0
do rr = 1, rrmax
call rec_read(infile, rec(rr))
if (rec(rr)%data_type .eq. ' ') exit
rlast = rr
call rec_print(outfile, rec(rr))
end do
close(infile)
close(outfile)
end program main