先に紹介した内部記述による可変長ファイルのレコード処理の方法は機能的には
全く問題がないのだが唯一、
「バッファー長がメンバー 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