バイナリデータの入出力
基礎知識
順番探査 (Sequential Access)
直接探査(Direct Access)
直接探査ファイルの使い方
http://mns2.c.u-tokyo.ac.jp/arasaki/fortran/direct.html
「書式なし直接探査ファイル (unformatted direct access file)」の特徴
- ファイルの途中の一部を読み書きできる
- 内部表現のまま読み書きされるので書式変換のオーバーヘッドがかからない (記憶容量・速度・精度の面で)
- ただし、すべての記録が同じ長さ
順番探査がテープをイメージしているなら直接探査はディスクのイメージです。
プログラム例1
書き出し
program write_direct
integer, parameter :: m=10
real, allocatable :: a(:),b(:)
character(100) ofname
ofname="tmp_direct_access.dat"
write(*,'(A,A)')'output file name: ',ofname
n=5
allocate(a(n),b(n))
do i=1,n
a(i)=i
b(i)=i*2.0
enddo !i
INQUIRE(IOLENGTH=nreclen)a,b
open(10,file=ofname,access='direct',recl=nreclen)
write(*,*)'Record length= ',nreclen
write(10,rec=1)a,b
write(*,'(A)')'output data:'
do i=1,n
write(*,*)a(i),b(i)
enddo
stop
end
$ ifort tmp_write_directac.f90 -o tmp_write_directac
$ ./tmp_write_directac
output file name: tmp_direct_access.dat
Record length= 10
output data:
1.000000 2.000000
2.000000 4.000000
3.000000 6.000000
4.000000 8.000000
5.000000 10.00000
読み込み
program read_direct
integer, parameter :: m=10
real, allocatable :: a(:),b(:)
character(100) ifname
ifname="tmp_direct_access.dat"
write(*,'(A,A)')'input file name: ',ifname
n=5
allocate(a(n),b(n))
INQUIRE(IOLENGTH=nreclen)a,b
open(10,file=ifname,access='direct',recl=nreclen)
write(*,*)'Record length= ',nreclen
read(10,rec=1)a,b
write(*,'(A)')'Input data'
do i=1,n
write(*,*)a(i),b(i)
enddo
stop
end
$ ifort tmp_read_directac.f90 -o tmp_read_directac
$ ./tmp_read_directac
input file name: tmp_direct_access.dat
Record length= 10
Input data
1.000000 2.000000
2.000000 4.000000
3.000000 6.000000
4.000000 8.000000
5.000000 10.00000
プログラム例2
データは、tとsの2種類ある。
1ヶ月ごとに、1レコードとしてまとまっている。
!
! 仮定しているデータファイルの構造
!
! レコード番号 データ
! 1 t,s
! ............
! 12 t,s
!
t,sの配列のサイズは(nx,ny,nz)
サンプルプログラム
real, allocatable(t(:,:,:), s(:,:,:))
integer, parameter :: nx=10,ny=20,nz=5
allocate (t(nx,ny,nz),s(nx,ny,nz))
INQUIRE(IOLENGTH=L) t,s
nt=12
iu2=20
open(iu2,file=infle2,form="unformatted",access='direct',recl=L)
print *, ' Reading t & s'
do m=1,nt
read(iu2,rec=m)t,s
enddo !m
close(iu2)
print *, 'Done.'
print *
stop
end