前回の「42.EBCDICでないIFSデータをRPGで読み取るには」で
EBCDICではないIFSのストリーム・ファイルを読み取る方法を紹介した。
今回はそのIFSのストリーム・ファイルを読んでDSPFに表示する方法を
紹介する。
_
例: PYTHONソースの表示]
PYTHON ソースの表示 プログラム : WSHOHIN.PTR ディレトリー /PYTHON/PROJECT/WSHOHIN 1 #*********************************************************# 2 #* 3 #* プログラム名 : WSHOHIN.PY 4 #* タイプ : PYTHON 5 #* APP タイプ : WEB 単票型テンプレート (WSGLCOL) 6 #* 作成日 : 2025/01/29 16:02:09 7 #* 作成者 : QTR 8 #* ディレクトリー : /PYTHON/PROJECT 9 #* 使用ファイル : QTRFIL/SHOHIN 10 #* QTRFIL/HINSHU 11 #* 監査報告書 : Y 12 #* 数値の編集 : Y 13 #* 画面サイズ 14 #* 桁 : 132 15 #* 行 : 27 続く ... デバッグ F3= 終了 F6= 停止点の追加 / 消去 F21= コマンド入力
[解説]
Pythonのソース・プログラムはUtf-8(=CCSID:1208)でIFSに保存されているが
先に説明した方法でオープンして読み取ってやればEBCDAICデータとして
DSPFに表示することができる。
これはその表示結果である。
_
[RPG: DSPPTNSRC ] Pythonソースの読み取りRPG
D LSTAT_ PR 10I 0 EXTPROC('lstat') D PATH * VALUE D INFO * VALUE D INFO DS 128 QUALIFIED D ALLOCSIZE 10U 0 OVERLAY(INFO:45) ファイル・サイズ D TMPBUF S * 一時バッファー D ANS S 1A D TOKENPTR S * D CRLF S 3A INZ(X'0D2500') D CRLF_P S * INZ(%ADDR(CRLF)) D TMPSRC S 132A BASED(TOKENPTR) : C****************************************************** C READ BEGSR C****************************************************** C*( データ・ベースの読み取り ) /FREE RES = LSTAT_(%ADDR(PROJECT): INFO_P);// 属性を取得 IF (RES = FALSE); // 失敗 PERROR_(%ADDR(ATTR)); CLOSE_(FD); RETURN; ENDIF; // 失敗 TMPLEN = INFO.ALLOCSIZE;// 割振り長を取得 IF ( TMPLEN < 0 ); // メモリー割り振り失敗 PERROR_(%ADDR(SUCCESS)); RETURN; ELSE; // メモリー割り振り成功 TMPBUF = %ALLOC(TMPLEN);// 動的にメモリを確保 BYTE_RED = READ_(FD: TMPBUF: TMPLEN); // READ 読取り ENDIF; // メモリー割り振り成功 CLOSE_(FD); /END-FREE C*( 読み取ったバッファーを分割する ) /FREE TOKENPTR = STRTOK_(TMPBUF: CRLF_P); DOW TOKENPTR <> *NULL; RRN1 = RRN1 + 1; IF RRN1 = 23; *IN50 = *OFF; ENDIF; SELECT; WHEN RRN1 >= 1000; GYO = %CHAR(RRN1); WHEN RRN1 >= 100; GYO = ' ' + %CHAR(RRN1); WHEN RRN1 >= 10; GYO = ' ' + %CHAR(RRN1); OTHER; GYO = ' ' + %CHAR(RRN1); ENDSL; POS = %SCAN(NULL:TMPSRC); PTNSRC = %SUBST(TMPSRC:1:%SCAN(NULL:TMPSRC) -1); //*-------------------------------------------------// WRITE SFREC01; //SFL レコードを追加 //*-------------------------------------------------// FLD3 = %SUBST(TMPSRC:POS+1:3); IF FLD3 = EBC_CRLF; // 次はスペース */ RRN1 = RRN1 + 1; PTNSRC = *BLANKS; WRITE SFREC01; //SFL レコードを追加 ENDIF; // 次はスペース */ IF DSPREC = 0; DSPREC = RRN1; ENDIF; TOKENPTR = STRTOK_(*NULL: CRLF_P); ENDDO; IF DSPREC = 0; ERR = 'E'; MSG = ' データの読み取りに失敗しました。 '; EXSR LRRTN; ENDIF; /END-FREE C REDEND ENDSR
[解説]
ストリーム・ファイルとはファイル全体がひとつの紐のようにつながっている
ファイルのことである。
IBM のDB2/400のようにレコード単位で読み取るのではなく
ファイル全体を一度に読み込まなければならない。
PCに比べてPowerSystemのメモリーが小さくて済んでいるのも
レコード単位での読み取りが可能であるからである。
そこでストリーム・ファイルを読み取るには一般的に次のような
手順が必要になる。
_
①ストリーム・ファイルの属性を入手する。
②ファイルの長さの分だけの動的メモリー・バッファーを
定義して確保する。
③そのメモリー・バッファーにファイルを読み込む
④ファイルをクローズする
⑤メモリー・バッファーを処理する
⑥最後にメモリー・バッファーを解放する
具体的には
①ストリーム・ファイルの属性を入手する。
RES = LSTAT_(%ADDR(PROJECT): INFO_P);// 属性を取得
によってファイル・サイズ:ALLOCSIZE を取得する。
②ファイルの長さの分だけの動的メモリー・バッファーを
定義して確保する。
TMPBUF = %ALLOC(TMPLEN);// 動的にメモリを確保
によって動的メモリー : TMPBUF を作成して確保する。
③そのメモリー・バッファーにファイルを読み込む
BYTE_RED = READ_(FD: TMPBUF: TMPLEN); // READ 読取り CLOSE_(FD);
⑤メモリー・バッファーを処理する
ここでいよいよDSPFのSFLレコードに動的メモリーを
分割して書き込む。
ストリーム・ファイルの切れ目(=改行コード)は一般的には
CRLF = 0x0d0a であるがもうすでに EBCDICに変換しているので
切れ目(=改行コード)もEBCDICに変換されており EBCDICの切れ目は
EBC_CRLF = 0x0d25 である。
TOKENPTR = STRTOK_(TMPBUF: CRLF_P); DOW TOKENPTR <> *NULL; : WRITE SFREC01; //SFL レコードを追加 TOKENPTR = STRTOK_(*NULL: CRLF_P); ENDDO;
この DOWはC言語の典型的な分割方法である。
_
この処理方法のC言語の解説は
を参照のこと。
今回はILE-RPGでCCSIDのコード変換をしないでもEBCDICで読み取る方法を紹介した。
この方法を使えばC言語がわからないRPGプログラマーでも安心して
IFSストリーム・ファイルを読み取るプログラムを作成できるはずであある。