【Fortran学習|初心者向け】FortranのI/O処理を堅牢にする!INQUIRE(IOLENGTH=…)による動的レコード長決定術

1. 導入:なぜレコード長の指定が重要なのか?

Fortranで直接アクセス(DIRECT ACCESS)ファイルを使用する際、必ず必要になるのが「RECL(レコード長)」の指定です。しかし、この数値をハードコード(直接書き込み)してしまうと、計算精度(単精度から倍精度への変更など)を変えた瞬間にファイルが壊れたり、別のマシンへプログラムを移植した際にエラーが発生したりする原因になります。INQUIRE文のIOLENGTH指定を活用すれば、これらの課題を一挙に解決し、ポータブルで保守性の高いコードを実現できます。

2. 基礎知識:レコード長とは何か?

Fortranのバイナリファイル(書式なしファイル)において、RECLは「1レコードが何バイトのデータを持つか」を定義するパラメータです。注意が必要なのは、この単位がコンパイラや環境(4バイト単位なのか、1バイト単位なのか)によって異なる場合がある点です。INQUIRE文は、ファイルを開く前に、変数の型やサイズから「このデータを格納するのに必要なサイズはいくつですか?」を環境に合わせて自動計算してくれる非常に便利な機能です。

3. 実装:手順と論理的な解説

実装の基本手順は以下の通りです。
1. 書き出したいデータ構造(変数や配列)を定義する。
2. INQUIRE(IOLENGTH=…)を呼び出し、その変数を引数に渡すことで、必要なレコード長を整数変数に格納する。
3. 取得したその整数値を、OPEN文のRECL引数に指定する。
この手順を踏むことで、手動で計算ミスを犯すリスクがなくなり、OSやコンパイラの違いを吸収した柔軟なプログラムが作成できます。

4. サンプルプログラム

以下のコードは、倍精度の配列を直接アクセスファイルに保存する際、動的にレコード長を決定する例です。

<サンプルコード>
program dynamic_recl_example
implicit none
integer :: i, rlen, ios
integer, parameter :: dp = kind(0.0d0) ! 倍精度を指定
real(kind=dp), dimension(10) :: data_array

! データの初期化
data_array = (/ (real(i, dp), i=1, 10) /)

! 1. INQUIREを使って、data_arrayを保存するために必要な長さを算出
! rlenに自動的に適切なバイト数が格納されます
inquire(iolength=rlen) data_array

! 2. 算出したrlenをRECLに渡してファイルを開く
open(unit=10, file=’data.bin’, access=’direct’, recl=rlen, status=’replace’, iostat=ios)

if (ios == 0) then
! 3. 書き込み実行
write(10, rec=1) data_array
print , “書き込み成功!レコード長(rlen) =”, rlen
close(10)
else
print , “ファイルを開けませんでした。”
end if
end program dynamic_recl_example

5. 応用・注意点:現場で役立つアドバイス

注意点:INQUIREで得られる値の単位は、必ずしも常に「バイト」とは限りません。コンパイラによっては「4バイトワード数」である場合もあります。しかし、OPEN文のRECLも同じ規格に従うため、INQUIREの結果をそのままOPENに渡せば、単位の不一致は発生しません。

現場での活用:構造体(派生型)を書き出す場合も同様です。複雑なデータ構造を扱う際、手計算でレコード長を算出するのは非常に危険です。常にINQUIREに計算を任せる習慣をつけることで、将来的な機能拡張やデータ型の変更にも強い、堅牢な計算プログラムを構築できます。

コメント

タイトルとURLをコピーしました