データセットI/O API
本付録では、データセットI/O APIを使用して、C言語で作成されたアプリケーション・プログラムでデータセットのレコードを読み書きする方法について説明します。
1. 概要
OpenFrameが提供するデータセットI/O APIを使用して、C言語で作成されたアプリケーション・プログラムで、JCLのDD文で割り当てられたデータセットのレコードを読み書きすることができます。
メインCOBOLアプリケーション・プログラムでオープンされたデータセットを、Cで作成されたサブプログラムで読み書きするなどのI/Oを行う場合は、FCD Handling APIライブラリを使用することをお勧めします。 |
データセットI/O APIを使用してプログラムを作成するには、OpenFrameバイナリと一緒に配布されるtcfh.hヘッダー・ファイルをユーザー・プログラムに含める必要があり、ユーザー・プログラムをコンパイルする際、libtcfh.soライブラリをリンクする必要があります。
データセットI/O APIは、以下のように分類できます。
-
ファイルのオープンとクローズ
API 説明 レコード処理のためにデータセットを開きます。
レコード処理のために開いていたデータセットを閉じます。
-
レコード・アクセス
API 説明 順次処理のために内部レコード・ポインターを移動させます。
データセットで1つのレコードを読み取ります。
データセットに1つのレコードを書き込みます。
データセットにある1つのレコードの内容を変更します。
データセットにある1つのレコードを削除します。
-
PDSメンバーの処理
API 説明 データセットのディレクトリ一覧を構成します。
データセットのディレクトリ一覧を検索します。
データセットのディレクトリ一覧を使用してメンバーにアクセスします。
データセットのメンバー名を使用してメンバーにアクセスします。
データセット・メンバーの追加、取り替え、変更、削除、初期化を行います。
2. ファイルのオープンとクローズ
2.1. tcfh_open()
レコード処理のためにデータセットを開きます。データセットを開く操作は、JCLのDD文で割り当てられたデータセットに対して、実際にレコードを読み書きするなどのI/Oを行うための準備作業です。
-
プロトタイプ
int tcfh_open(tcfh_file_t *file, int open_mode, int flags);
-
パラメータ
パラメータ 説明 file(入出力)
オープンするデータセットの情報を保存するファイル構造体です。
open_mode(入力)
データセットのオープン・モードです。
-
INPUT
-
OUTPUT
-
INOUT
-
EXTEND
flags(入力)
データセットのオープン・オプションです。
-
NO REWIND
-
-
戻り値
正常に実行された場合は0を返し、エラーが生じた場合は負数のエラーコードを返します。
-
参考
データセットを開くためには、オープンするデータセットの情報を保存したファイル構造体のポインターを提供する必要があります。このファイル構造体は、tcfh.hヘッダー・ファイルに定義されています。
/* -------------------------- file I/O block --------------------------- */ typedef struct tcfh_file_s { char file_name[8+2]; /* file name - SELECT clause */ char file_status[2]; /* file status - I/O interface */ uint8_t organization; /* organization - SELECT clause */ uint8_t access_mode; /* access mode - SELECT clause */ uint8_t open_mode; /* open mode - tcfh_open() */ uint8_t misc_flags; /* miscellaneous - SELECT clause */ /* 64 bit separating line */ char file_path[256]; /* file path - tcfh_open() */ /* 64 bit separating line */ int32_t file_handle; /* file handle - tcfh_open() */ int32_t relative_key; /* relative key - C(C++) program */ /* 64 bit separating line */ int16_t key_length; /* key length - DCL statement */ int16_t key_loc; /* key position - DCL statement */ int16_t rec_size; /* record size - DCL statement */ int16_t cur_reclen; /* current record length - I/O interface */ ... } tcfh_file_t;
前述したファイル構造体で、データセットを開く際に指定が必要な項目は以下のとおりです。
項目 説明 file_name
JCLに記述されたDD名です。
organization
データセットの構造です。
-
0: 順次
-
1: 相対
-
2: 索引
acess_mode
アクセス・モードです。
-
0: 順次
-
1: 任意
-
2: 両方
データセットを開くとき、tcppfh_open() APIのパラメータでオープン・モードを指定する必要があります。以下は、サポートされるデータセットのオープン・モードです。
マクロ オープン・モード 説明 TCFH_OPEN_INPUT
0
INPUTモードです。
TCFH_OPEN_OUTPUT
1
OUTPUTモードです。
TCFH_OPEN_INOUT
2
INPUT/OUTPUTモードです。
TCFH_OPEN_EXTEND
3
EXTENDモードです。
データセットが正常に開かれた場合、ファイル構造体のfile_status、file_path、file_handleなどの値が設定されます。
-
2.2. tcfh_close()
レコード処理のために開いていたデータセットを閉じます。データセットを閉じる操作は、アプリケーションでデータセットを読み書きするなどのI/Oを行った後、アプリケーションと物理的なデータセットとの接続を切断する作業です。
-
プロトタイプ
int tcfh_close(tcfh_file_t *file, int flags);
-
パラメータ
パラメータ 説明 file(入出力)
閉じるデータセットの情報を保存したファイル構造体です。
flags(入力)
データセットのクローズ・オプションです。
-
WITH LOCK
-
-
戻り値
正常に実行された場合は0が返され、エラーが生じた場合は負数のエラーコードが返されます。
-
参考
以下は、CLOSEコマンドを使用時の注意事項です。
-
tcfh_close() APIのfileパラメータには、tcfh_open() APIに提供されたファイル構造体のポインターを渡します。
-
tcfh_close() APIを使用して正常に閉じたデータセットは、tcfh_open() APIを使用して再オープンすることができます。
-
3. レコード・アクセス
3.1. tcfh_start()
相対データセット、または索引データセットで次に読み取るレコードの位置に内部レコード・ポインターを移動させます。移動させるレコードの位置は、相対データセットの場合は、ファイル構造体のrelative_keyフィールドに相対レコード番号を指定し、索引データセットの場合は、tcfh_start() APIのkeyパラメータにキー値を指定します。
-
プロトタイプ
int tcfh_start(tcfh_file_t *file, char *key, int keylen, int flags);
-
パラメータ
パラメータ 説明 file(入出力)
処理するデータセットの情報を保存したファイル構造体です。
key(入出力)
索引データセットのキー値です。
keylen(入力)
索引データセットのキー長です。
flags(入力)
データセットのSTARTオプションです。
-
EQUAL
-
GTEQ
-
-
戻り値
正常に実行された場合は0を返し、エラーが生じた場合は負数のエラーコードを返します。
-
注意事項
以下は、STARTコマンドを使用時の注意事項です。
-
データセットをINPUTまたはINOUTモードで開いた場合にのみ、STARTコマンドを実行できます。
-
コマンドを実行した後、ファイル構造体のfile_statusでファイルの状態をチェックすることができます。
-
相対データセットの場合、RRNはファイル構造体のrelative_keyフィールドを使用します。
-
3.2. tcfh_read()
データセットのレコードを順次に読み取るか、キーを指定してランダムに読み取ります。
ランダムにレコードを読み取る際、相対データセットの場合は、ファイル構造体のrelative_keyフィールドに相対レコード番号を指定し、索引データセットの場合は、tcfh_read() APIのkeyパラメータにキー値を指定します。
順次にデータセットのレコードを読み取る場合は、tcfh_read() APIのflagsパラメータにTCFH_READ_NEXTマクロを指定し、ランダムにレコードを読み取る場合は、TCFH_READ_DEFAULTマクロを指定します。
可変長レコード・データセットの場合は、READコマンドを使用してデータセットのレコードを読み取るとき、ファイル構造体のcur_reclenフィールドを調べて読み取ったレコードの長さを取得することができます。取得したレコード長は、tcfh_read() APIのbufパラメータに指定されたバッファーにコピーされたレコード・データの長さ、つまり、RDWを除いたレコードのデータ部分の長さです。
-
プロトタイプ
tcfh_read(tcfh_file_t *file, char *key, int keylen, char *buf, int buflen, int flags);
-
パラメータ
パラメータ 説明 file(入出力)
処理するデータセットの情報を保存したファイル構造体です。
key(入出力)
索引データセットのキー値です。
keylen(入力)
索引データセットのキー長です。
buf(出力)
レコード・データを保存するためのバッファーです。
buflen(入力)
レコード・データのバッファー・サイズです。
flags(入力)
データセットのREADオプションです。
-
DEFAULT
-
NEXT
-
-
戻り値
正常に実行された場合は0を返し、エラーが生じた場合は負数のエラーコードを返します。
-
注意事項
以下は、READコマンドを使用時の注意事項です。
-
データセットをINPUTまたはINOUTモードで開いた場合にのみ、READコマンドを実行できます。
-
コマンドを実行した後、ファイル構造体のfile_statusでファイルの状態をチェックすることができます。
-
相対データセットの場合、RRNはファイル構造体のrelative_keyフィールドを使用します。
-
読み取ったレコードのデータ長は、ファイル構造体のcur_reclenフィールドで取得します。
-
3.3. tcfh_write()
データセットに新しいレコードを記録します。順次データセットはデータセットの最後にレコードを記録し、相対データセットはファイル構造体のrelative_keyフィールドに指定された相対レコード番号の位置に記録します。索引データセットは、tcfh_write() APIのkeyパラメータに指定されたキー順にレコードが保存されます。
可変長レコード・データセットの場合は、WRITEコマンドを使用してデータセットのレコードを記録するとき、記録するレコードの長さをtcfh_write() APIのbuflenパラメータに指定します。指定するレコードの長さは、tcfh_write() APIのbufパラメータで指定されたバッファーに保存されているレコード・データの長さ、つまり、RDWを除いたレコードのデータ部分の長さを指定します。
-
プロトタイプ
tcfh_write(tcfh_file_t *file, char *key, int keylen, char *buf, int buflen, int flags);
-
パラメータ
パラメータ 説明 file(入出力)
処理するデータセットの情報を保存したファイル構造体です。
key(入出力)
索引データセットのキー値です。
keylen(入力)
索引データセットのキー長です。
buf(出力)
レコード・データを保存しているバッファーです。
buflen(入力)
レコード・データの長さです。
flags(入力)
データセットのWRITEオプションです。
-
戻り値
正常に実行された場合は0を返し、エラーが生じた場合は負数のエラーコードを返します。
-
注意事項
以下は、WRITEコマンドを使用時の注意事項です。
-
OUTPUT、INOUTまたはEXTENDモードで開いた場合にのみ、WRITEコマンドを使用できます。
-
INOUTモードで開いた場合、順次アクセスによる書き込みはできません。
-
コマンドを実行した後、ファイル構造体のfile_statusでファイルの状態をチェックすることができます。
-
相対データセットの場合、RRNはファイル構造体のrelative_keyフィールドを使用します。
-
3.4. tcfh_rewrite()
データセットにある既存のレコードの内容を変更します。相対データセットは、ファイル構造体のrelative_keyフィールドに指定された相対レコード番号の位置にあるレコードを変更します。索引データセットは、tcfh_rewrite() APIのkeyパラメータで指定されたキー順に合ったレコードが変更されます。
可変長レコード・データセットの場合は、REWRITEコマンドを使用してデータセットのレコードを変更するとき、変更するレコードの長さをtcfh_rewrite() APIのbuflenパラメータに指定します。指定するレコードの長さは、tcfh_rewrite() APIのbufパラメータに指定されたバッファーに保存されているレコード・データの長さ、つまり、RDWを除いたレコードのデータ部分の長さを指定します。
-
プロトタイプ:
tcfh_rewrite(tcfh_file_t *file, char *key, int keylen, char *buf, int buflen, int flags);
-
パラメータ
パラメータ 説明 file(入出力)
処理するデータセットの情報を保存したファイル構造体です。
key(入力)
索引データセットのキー値です。
keylen(入力)
索引データセットのキー長です。
buf(入力)
レコード・データを保存しているバッファーです。
buflen(入力)
レコード・データの長さです。
flags(入力)
データセットのREWRITEオプションです。
-
戻り値
正常に実行された場合は0を返し、エラーが生じた場合は負数のエラーコードを返します。
-
注意事項
以下は、REWRITEコマンドを使用時の注意事項です。
-
データセットをINOUTモードで開いた場合にのみ、REWRITEコマンドを使用できます。
-
順次アクセスの場合、REWRITEコマンドの実行前に、READコマンドで変更するレコードを読み取ります。
-
コマンドを実行した後、ファイル構造体のfile_statusでファイルの状態をチェックすることができます。
-
相対データセットの場合、RRNはファイル構造体のrelative_keyフィールドを使用します。
-
3.5. tcfh_delete()
相対データセットまたは索引データセットのレコードを削除します。相対データセットの場合は、ファイル構造体のrelative_keyフィールドに指定された相対レコード番号の位置にあるレコードを削除します。索引データセットの場合は、tcfh_delete() APIのkeyパラメータで指定されたキー順に合ったレコードが削除されます。
-
プロトタイプ
int tcfh_delete(tcfh_file_t *file, char *key, int keylen, int flags);
-
パラメータ
パラメータ 説明 file(入出力)
処理するデータセットの情報を保存したファイル構造体です。
key(入力)
索引データセットのキー値です。
keylen(入力)
索引データセットのキー長です。
flags(入力)
データセットのDELETEオプションです。
-
戻り値
正常に実行された場合は0を返し、エラーが生じた場合は負数のエラーコードを返します。
-
注意事項
以下は、DELETEコマンドを使用時の注意事項です。
-
データセットをINOUTモードで開いた場合にのみ、DELETEコマンドを使用できます。
-
順次アクセスの場合、DELETEコマンドの実行前に、READコマンドで削除するレコードを読み取る必要があります。
-
コマンドを実行した後、ファイル構造体のfile_statusでファイルの状態をチェックすることができます。
-
相対データセットの場合、RRNはファイル構造体のrelative_keyフィールドを使用します。
-
4. PDSメンバーの処理
4.1. tcfh_bldl()
PDSのディレクトリ一覧を構成します。
-
プロトタイプ
int tcfh_bldl(tcfh_file_t *file, char *filter);
-
パラメータ
パラメータ 説明 file(入出力)
処理するデータセットの情報を保存したファイル構造体です。
filter(入力)
リストを構成するメンバーに制限を与える値です。データセットのメンバー全体をリストで構成する場合は、アスタリスク(*)またはNULL値を指定します。「ABC」で始まるメンバーのみを構成する場合は、filterに「ABC」値を指定します。
-
戻り値
正常に実行された場合はディレクトリ一覧を構成したメンバーの数を返し、エラーが生じた場合は負数のエラーコードを返します。
-
参考
以下は、BLDLコマンドを使用時の注意事項です。
-
コマンドの実行後、ファイル構造体のfile_statusでファイルの状態をチェックすることができます。
-
4.2. tcfh_bldl_info()
PDSのディレクトリ一覧を検索します。tcfh_bldl()を実行した後に使用できます。
データセットのレコードを順次に読み取る場合は、tcfh_read()のflagsパラメータにTCFH_READ_NEXTマクロを指定し、ランダムに読み取る場合は、TCFH_READ_DEFAULTマクロを指定します。
可変長レコード・データセットの場合は、READコマンドを使用してデータセットのレコードを読み取るとき、ファイル構造体のcur_reclenフィールドを調べて読み取ったレコードの長さを取得できます。取得したレコード長は、tcfh_read()のbufパラメータで指定されたバッファーにコピーされたレコード・データの長さ、つまり、RDWを除いたレコードのデータ部分の長さです。
-
プロトタイプ
int tcfh_bldl_info(tcfh_file_t *file, int number, tcfh_membstat_t *stat);
-
パラメータ
パラメータ 説明 file(入出力)
処理するデータセットの情報を保存したファイル構造体です。
number(入力)
ディレクトリ一覧での相対アドレス値です。
stat(出力)
索引データセットのキー長です。
-
戻り値
正常に実行された場合は0を返し、エラーが生じた場合は負数のエラーコードを返します。
-
参考
メンバー情報を検索するには、メンバーの情報を保存したファイル構造体のポインターを提供する必要があります。このファイル構造体は、tcfh.hヘッダー・ファイルに定義されています。
/* -------------------------- file I/O block --------------------------- */ typedef struct tcfh_membstat_s { char member[64]; int64_t size; char lastmoddt[8+2]; /* last modified date */ char lastmodtm[6+2]; /* last modified time */ } tcfh_membstat_t;
上記のファイル構造体で情報を提供する項目は以下のとおりです。
項目 説明 member(出力)
PDSのメンバー名が記述されます
size(出力)
メンバーが保存されたUNIXファイルのサイズを表示します。
lastmoddt(出力)
メンバーの最終修正日付を表示します。
lastmodtm(出力)
メンバーの最終修正時刻を表示します。
4.3. tcfh_find_by_bldl()
PDSのメンバーにアクセスします。tcfh_bldl()を実行した後に使用できます。
-
プロトタイプ
int tcfh_find_by_bldl(tcfh_file_t *file, int num);
-
パラメータ
パラメータ 説明 file(入出力)
処理するデータセットの情報を保存したファイル構造体です。
num(入力)
索引データセットのキー値です。
-
戻り値
正常に実行された場合は0を返し、エラーが生じた場合は負数のエラーコードを返します。
-
参考
以下は、FINDコマンドを使用時の注意事項です。
-
コマンドの実行後、ファイル構造体のfile_statusでファイルの状態をチェックすることができます。
-
4.4. tcfh_find_by_name()
PDSのメンバーにアクセスします。tcfh_bldl()の実行に関係なく使用できます。
-
プロトタイプ
int tcfh_find_by_name(tcfh_file_t *file, char *name);
-
パラメータ
パラメータ 説明 file(入出力)
処理するデータセットの情報を保存したファイル構造体です。
name(入力)
アクセスするメンバー名を指定します。
-
戻り値
正常に実行された場合は0を返し、エラーが生じた場合は負数のエラーコードを返します。
-
参考
以下は、FINDコマンドを使用時の注意事項です。
-
コマンドの実行後、ファイル構造体のfile_statusでファイルの状態をチェックすることができます。
-
4.5. tcfh_stow()
PDSにメンバーを追加、取り替え、削除、初期化、およびメンバー名を変更します。
-
プロトタイプ
int tcfh_stow(tcfh_file_t *file, char *name, int flags);
-
パラメータ
パラメータ 説明 file(入出力)
処理するデータセットの情報を保存したファイル構造体です。
name(入力)
処理するメンバー名を記述します。スラッシュ(/)記号を使って変更前と変更後のメンバー名を区切ります。
(例: "BEFORE/AFTER" )
flags(入力)
データセットのSTOWオプションです。
-
TCFH_STOW_ADD
-
TCFH_STOW_DELETE
-
TCFH_STOW_CHANGE
-
TCFH_STOW_REPLACE
-
TCFH_STOW_INITIALIZE
-
-
戻り値
正常に実行された場合は0を返し、エラーが生じた場合は負数のエラーコードを返します。
-
注意事項
以下は、STOWコマンドを使用時の注意事項です。
-
メンバーを追加、取り替える場合、WRITEコマンドが先に実行される必要があります。
-
コマンドの実行後、ファイル構造体のfile_statusでファイルの状態をチェックすることができます。
-
5. ファイル・ステータス・コード
データセットの読み書きを実行した後、データセットの状態を確認するには、データセットの情報を保存しているファイル構造体のfile_statusフィールドを調べます。file_statusフィールドには、データセットの状態コードを保存されています。
以下は、データセットのステータス・コードについての説明です。
コード | 説明 |
---|---|
00 |
作業が正常に完了した場合です。 |
02 |
索引ファイルの場合、重複キーが許可されているデータセットに重複キーが発生した場合です。 |
10 |
次のレコードがない場合です。(ファイルを最後まで読み取った場合) |
22 |
索引ファイルや相対ファイルに対し、重複キー・エラーが発生した場合です。 |
23 |
キーに該当するレコードが見つからなかった場合です。 |
37 |
指定されたオープン・モードがサポートされない場合です。 |
38 |
ロックされたファイルを開こうとした場合です。 |
39 |
データセットの属性が正しく指定されていない場合です。 |
41 |
すでに開いているファイルを開こうとした場合です。 |
42 |
すでに閉じられているファイルを閉じようとした場合です。 |
43 |
順次モードでREWRITEまたはDELETEコマンドの実行前のコマンドがREADコマンドでない場合です。 |
44 |
INPUT/INOUT以外のモードで、READ/STARTコマンドを実行した場合です。 |
47 |
INPUT/INOUT以外のモードで、READ/STARTコマンドを実行した場合です。 |
48 |
OUTPUT/INOUT/EXTEND以外のモードで、WRITEコマンドを実行した場合です。 |
49 |
INOUT以外のモードで、DELETE/REWRITEコマンドを実行した場合です。 |
99 |
システム・エラーが発生した場合です。 |