更新ログ:2021/05/01 ご指摘いただいた事項を修正しました!
ありがとうございました。
Frotranを拡張していろいろ盛り込んだIOを作りました。
↓こちらのsrc/IOClass/IOClass.f90
にコード等があります。
私は物覚えが悪くコーディングが苦手なので、そんな私でも気軽にコードを書けるライブラリを目指しています。
しばらく運用してきて、今では当たり前になっている程ちょっと便利なあれこれをメモします。
ファイルOpen, write, close
ファイルを書き込み専用で開き、文字を書き、閉じます。
program main
use IOClass
implicit none
type(IO_) :: f
call f%open("hello.txt",'w')
call f%write("Hello, world!")
call f%close()
end program main
もちろん、pythonを真似ています。
IOクラスのインスタンスに面倒なことを全部押し込めて、制約はあるものの最小限のことはストレスなしにできます。
なお、読み込み専用で開いて書き込もうとした場合、エラーが出ます。
program main
use IOClass
implicit none
type(IO_) :: f
call f%open("hello.txt",'r') ! 読み込み専用
call f%write("Hello, world!")!書き込もうとする
call f%close()
end program main
実行結果:
IOClass >> Error >> This file is readonly.
Nothing is written.
配列の書き出し
配列も書き出せます。疑似乱数の入った配列を書き出します。
program main
use IOClass
use RandomClass
implicit none
type(IO_) :: f
! ランダム配列を作成
type(Random_) :: random
real(real64),allocatable :: matrix(:,:)
matrix = random%randn(5,3)
! ファイルへ出力
call f%open("hello.txt",'w')
call f%write(matrix)
call f%close()
end program main
実行結果:
0.67536126921419082 0.69757660370274011 0.60094521743857499
0.59806235391600904 0.74967556553758152 0.90754945224994465
0.75558385131066363 0.12390139489396934 0.79041193308025293
8.6508975968684232E-002 0.22201368894750784 0.51021838491468208
0.26723752139363488 0.90740198182976362 0.11228899238368861
一行ずつ最終行まで読み込む
全部文字列型として読み込まれます。
program main
use IOClass
use RandomClass
implicit none
type(IO_) :: f
! 1行ずつ読み込み
call f%open("hello.txt",'r')
do
if(f%EOF) exit !End of Fileを検出
call print( f%readline() )
enddo
call f%close()
end program main
出力
0.67536126921419082 0.69757660370274011 0.60094521743857499
0.59806235391600904 0.74967556553758152 0.90754945224994465
0.75558385131066363 0.12390139489396934 0.79041193308025293
8.6508975968684232E-002 0.22201368894750784 0.51021838491468208
0.26723752139363488 0.90740198182976362 0.11228899238368861
ベクトルを読み込む例:
program main
use IOClass
use ArrayClass
implicit none
type(IO_) :: f
real(real64),allocatable :: a(:)
integer(int32) :: vector_size,k
! 1行ずつ読み込み
call f%open("hello.txt",'r')
call f%read(vector_size)
! vector_sizeの大きさのベクトルを、成分すべてゼロで埋めて初期化
a = zeros(vector_size)
k=0
do k=1,vector_size
call f%read(a(k) )
enddo
call f%close()
end program main
今後、追加したい機能ができたり、リクエストを頂いたら機能を充実させようと思います。
2021/04/30 13:00追記
このままだとpythonの劣化版コピーになりそうなので、少し変な例を追記します。
MPIを使って無駄に複数プロセスから連番ファイルを作成します。
program main
use IOClass
use RandomClass
use MPIClass
implicit none
type(IO_) :: f
type(MPI_) :: mpid
type(Random_) :: random
real(real64),allocatable :: matrix(:,:)
! MPIプロセスを起動
call mpid%start()
! プロセスごとに乱数配列生成
matrix = random%randn(5,2)
! RandomArray+[各プロセスのID:0~n]+.txt のファイル名で書き込み
call f%open("RandomArray"//str(mpid%myrank)//".txt",'w')
call f%write(matrix)
call f%close()
! MPIプロセスを終了
call mpid%end()
end program main
実行結果(ファイルの中身をtailで表示しています):
==> RandomArray0.txt <==
0.13358124007489824 0.30942756280821027
0.91429368767347441 3.6723915916362371E-003
0.79563657553889677 7.5968026161326585E-002
0.52397486475551402 0.10411972865166408
0.98648440745513211 0.34160400739322294
==> RandomArray1.txt <==
0.58591290030779586 0.27005717525812956
0.74099504929005300 0.27308210837237179
0.24246487752131585 0.52686351576746970
1.7073996870589081E-002 0.77873768203914484
0.70074166638753155 0.90150905063838749
==> RandomArray2.txt <==
0.18961760714972586 0.24390471147059178
0.14709164649379058 0.17226645744811075
0.57021241598938266 0.24058007257742742
5.0949403785039871E-002 0.81951667425579844
0.73324091042227757 0.78762545339124646
==> RandomArray3.txt <==
0.74468275167468678 0.59067804940089152
0.97496026030280525 0.29655465505147727
0.42163374300476952 0.13652505186054953
0.22036072578754673 0.61955516343189088
0.37554403953208015 0.17710431989767361
乱文失礼いたしました。