web-dev-qa-db-ja.com

Fortranのフォーマットされていないファイルでの予期しない「埋め込み」

Fortranでフォーマットされていないファイルのフォーマットがわかりません。

例えば:

open (3,file=filename,form="unformatted",access="sequential")
write(3) matrix(i,:)

行列の列をファイルに出力します。ファイルの両端に4バイトが埋め込まれていることがわかりましたが、その理由や、この動作を制御する方法がよくわかりません。パディングを削除する方法はありますか?

19
Andrew Spott

書式なしIOの場合、Fortranコンパイラーは通常、レコードの長さをレコードの最初と最後に書き込みます。すべてではありませんが、ほとんどのコンパイラは4バイトを使用します。これは、レコードの読み取りに役立ちます。たとえば、最後の長さがバックスペース操作に役立ちます。これは、他の言語との互換性のために追加されたFortran 2003の新しいStream IOモードで抑制できます。openステートメントでaccess = 'stream'を使用してください。

22
M. S. B.

この正確な理由により、フォーマットされていない出力でシーケンシャルアクセスを使用したことはありません。ただし、それはアプリケーションによって異なり、レコード長インジケーター(特に非構造化データの場合)があると便利な場合があります。 steabertが gnuplotのfortranからのバイナリ出力を見る で示唆しているように、キーワード引数ACCESS = 'DIRECT'を使用してこれを回避できます。この場合、レコード長を指定する必要があります。この方法は、大きな多次元構造化データ(一定のレコード長)を効率的に格納するのに便利です。次の例では、サイズが配列のサイズと等しいフォーマットされていないファイルを書き込みます。

REAL(KIND=4),DIMENSION(10) :: a = 3.141
INTEGER                    :: reclen

INQUIRE(iolength=reclen)a
OPEN(UNIT=10,FILE='direct.out',FORM='UNFORMATTED',&
     ACCESS='DIRECT',RECL=reclen)
WRITE(UNIT=10,REC=1)a
CLOSE(UNIT=10)

END

これは、移植性の点で理想的なアプローチではないことに注意してください。直接アクセスで記述されたフォーマットされていないファイルでは、各要素のサイズに関する情報はありません。データサイズを説明するreadmeテキストファイルは、私にとってはうまく機能します。私は、シーケンシャルモードでパディングするのではなく、この方法を好みます。

6
milancurcic

Fortran IOはストリームベースではなくレコードベースです。write()を介して何かを書き込むたびに、データを書き込むだけでなく、そのレコードの開始マーカーと終了マーカーも書き込みます。両方のレコードマーカーはそのレコードのサイズです。これが、1回の書き込みで実数の束を書き込む(1つのレコード:1つの開始マーカー、1つの実数のバンチ、1つの終了マーカー)が、それぞれの書き込みに関して異なるサイズになる理由です。別の書き込みで実数(複数のレコード、それぞれ1つの開始マーカー、1つの実数、および1つの終了マーカー)。これは、不適切に書き込まれると占有を膨らませる可能性があるため、大きな行列を書き留める場合は非常に重要です。

5
Stefano Borini

Fortran Unformatted IOインテルとGnuコンパイラーを使用したさまざまな出力にかなり精通しています。幸いにも、1970年代のIBMにさかのぼる私の豊富な経験により、デコードが可能になりました。Gnuは4バイトの整数カウンターでレコードを埋め、レコード長。インテルは、1バイトのカウンターといくつかの埋め込みコーディング値を使用して、継続レコードまたはカウントの終了を示します。1バイトしか使用していなくても、非常に長いレコード長を使用できます。どちらかのコンパイラーによって生成されたフォーマットされていないファイルを読み取ることができるように変更する必要があるGnuコンパイラー。これにより、検出されたフォーマットを検出する必要があります。 「永遠に」Gnuのfgetcを使用するか、ファイルをストリームモードで開く。ファイルをGnuが期待するものに変換すると、最大で100倍の速度になります。検出と変換を行うかどうかは、ファイルサイズによって異なります。私は減らしたプログラムの起動時間(フォーマットされていない大きなファイルを開く)が5分から10秒に短縮されました。ユーザーがファイルをインテルのコンパイル済みプログラムに戻したい場合は、再変換するオプションを追加する必要がありました。それはすべて苦痛ですが、そこに行きます。

1
William Jacobs