前回の「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ストリーム・ファイルを読み取るプログラムを作成できるはずであある。
