先に紹介した内部記述による可変長ファイルのレコード処理の方法は機能的には
全く問題がないのだが唯一、
「バッファー長がメンバー SHOHIN のレコードより大きい 」
という警告メッセージが出力されてしまうことが問題といえば問題である。
これは 9999 バイトのバッファー長が実際に読み取ったデータ・ベースのレコード長より大きい、
ということが警告メッセージとして出力されているのである。
そこでここに紹介するサンプルは Cランタイム・ライブラリーの
Ropen, Rclose, Rreadn
という C/400 の関数を使う方法である。
C/400 のために用意されているこれらの関数は、すべてレコード長を指定して読み取ることが
できる機能がある。
従ってファイルをオープンしてからファイルの属性の中からレコード長を取り出して
レコード長を指定して読み取るようにすれば、先の警告メッセージが出力されることはない。
ただし、これらの関数は Cランタイム・ライブラリーの *SRVPGM の公開関数として
定義されているのだが、RPG のための RPG プロトタイプのソースは提供されていない。
C/400 のためのプロトタイプ・ソース : QSYSINC/H(RECIO) のメンバーを見ながら
RPG のソースを作成していたのでは莫大な時間がかかってしまうので
米国で Scott Klement 氏が無償でオープン・ソースとして公開してくれている
RPG 用のプロトタイプ・ソースがあるのでこれを借用することとした。
ただしサンプル・ソースは全くオリジナルとして作成されたものである。
-------------------------------------------------------------------------------
0001.00 H DFTNAME(TESTVAR2) DATEDIT(*YMD/) BNDDIR('QC2LE') DFTACTGRP(*NO)
0002.00 F********** 可変長ファイルの読取り (2) *******************************
0003.00 F*
0004.00 F**********************************************************************
0005.00
0006.00 /COPY PGMRLIB/QRPGLESRC,RECIO_H
0007.00
0008.00 D myFile DS likeds(rfile_t)
0009.00 D based(p_myFile)
0010.00 D opfb DS likeds(xxopfb_t)
0011.00 D based(p_opfb)
0012.00 D iofb DS likeds(RIOFB_T)
0013.00 D based(p_iofb)
0014.00
0015.00 D recLen S 10I 0
0016.00 D Data S 5000A
0017.00 D dsp40 S 40A
0018.00 D ans S 1A
0019.00
0020.00
0021.00 /FREE
0022.00 p_myFile = Ropen('QTRFIL/SHOHIN': 'rr');
0023.00 p_opfb = Ropnfbk(myFile); // オープン・フィードバック域を取得
0024.00 recLen = opfb.pgm_Record_len; // レコード長を取得
0025.00
0026.00 dow *inlr = *OFF;
0027.00 p_iofb = Rreadn(myFile : Data: recLen: r_DFT);
0028.00 if (iofb.num_bytes = EOF); // EOF になったら読取り終了
0029.00 leave;
0030.00 endif;
0031.00 dsp40 = Data;
0032.00 dsply dsp40;
0033.00 enddo;
0034.00 Rclose(myFile);
0035.00 dsply '*EOF' '' ANS;
0036.00
0037.00 *inLR = *ON;
0038.00 /END-FREE
-------------------------------------------------------------------------------
Ropen によって任意のファイルをオープンしてファイル識別子 : myFile を取得する。
myFile によってオープン・フィードバック域 obfb を取得してレコード長 recLen を取得する。
レコード長 recLen を指定して
p_iofb = Rreadn(myFile : Data: recLen: r_DFT);
として Rreadn 関数によって読み取る。
EOF になったら Rclose 関数によってファイルをクローズする。
このように Ropen, Rreadn, Rclose, ... 関数は柔軟で極めてシンプルでもある。
これらの関数は C言語の一般的なものではなく System i だけの上で IBM によって提供されているものである。
他にも Ropen, Rreadn, Rclose, ... の利用方法は数多くあるはずである。
[ 参考 ] RECIO_H