GT.Mは、シーケンシャルファイルへのアクセスを提供します。これらのファイルは、レコードへの直線的なアクセスをallow(許可)します。シーケンシャルファイルは、プログラムやレポートの保存を作成したり、GT.M.の外部の機能との通信(ファイル交換)に使用されます。
プロセスがCLOSEしてその後デバイスを再びOPENした時に、それらが以前に最後のCLOSEで持っていた値にデバイスパラメータで明示的に指定されていない特性をGT.Mが復元すること、ANSI規格は指定します。しかし、以前のOPEN状態を保証するために大規模なメニュー駆動型のアプリケーションは困難であるので、GT.Mは常にOPENでそれらのデフォルト値に指定されていないシーケンシャルファイルの特性をセットします。また、このアプローチは、プロセスの寿命までの間に、多数のシーケンシャルファイルをOPENしたりCLOSEしたりすることによって課される潜在的なメモリのオーバーヘッドを減します。
GT.Mは、複数のOPENコマンドを制限しません。しかし、もしファイルが既に開いている場合は、GT.Mは、USEのためだけに存在するRECORDSIZEとデバイスパラメータを除いて、シーケンシャルファイルのOPENの特性を変更する試みを無視します。
シーケンシャルファイルは、READONLY または read/write(NOREADONLY)となることが可能です。
シーケンシャルファイルは、FIXEDまたはVARIABLE(NOFIXED)のいずれかの長さのレコードで構成することができます。デフォルトでは、レコードは可変長(VARIABLE length)です。
GT.MがシーケンシャルファイルをOPENする時に、UNIXはその標準的なセキュリティを適用します。これは、ファイルを検索または作成するために必要な任意のディレクトリへのアクセスが含まれています。もしあなたがファイルをOPENできない場合、システム管理者に連絡してください。
シーケンシャルファイルI/O操作は、ファイルポインタと呼ばれる構造を使用します。ファイルポインタは、読書きのために次のレコードを論理的に識別します。OPENコマンドは、ファイルの先頭(REWIND)に、または、ファイルの終わり(APPEND)に、ファイルポインタを置きます。APPENDは、現在開いているファイルを再位置づけできません。各レコードの位置が以前のレコードに依存しているため、WRITEは、ファイル内の後続レコードへのファイルポインタを確実に移動する能力を破壊します。したがって、デフォルトでは(NOTRUNCATE)、ファイルポインタがファイルの末尾に配置されている場合にのみ、GT.M は書き込みを許可します。
以前に作成され保持されるべきデータが格納されているファイルは、デバイスのパラメータの APPENDでも開くことができます。
もしデバイスがTRUNCATEを有効にしている場合、ファイルポインタがファイルの末尾にない時、発行されるWRITEは、廃棄される現在のファイルポインタの後の位置に、すべてのコンテンツを書き込みます。これは、効果的に現在の位置にファイルの末尾を移動して、WRITEを許可します。
LF ($CHAR(10)) は、すべてのMモードのシーケンシャル・ファイル、TRM、PIPE、FIFOの論理レコードを終了します。文字セットがMでない非固定(non FIXED)フォーマットのシーケンシャル・ファイルおよび端末デバイスの場合、すべての標準Unicode行ターミネータが論理レコードを終了します。U+000A (LF), U+0000D (CR), U+000D に続くU+000A (CRLF), U+0085 (NEL), U+000C (FF), U+2028 (LS) and U+2029 (PS)
次の表は、自動レコード終了が有効(WRAP)または無効(NOWRAP)のSTREAM、VARIABLE、FIXED形式のシーケンシャルファイルのREADおよびWRITE操作をすべて示しています。
コマンド |
WRAP または NOWRAP |
STREAM または VARIABLE形式ファイルの動作 |
FIXED 形式ファイルの動作 |
|
---|---|---|---|---|
READ フォーマット または WRITE または WRITE * |
WRAP |
引数全体を書きますが、$XがWIDTHを超えようとするときはいつでも:<LF>文字を挿入し、$Xを0に設定し、$Yをインクリメントします |
VARIABLEに似ていますが、<LF> ではありません |
|
READ フォーマット または WRITE または WRITE * |
NOWRAP |
下記のようにSTREAMまたはVARIABLE形式に基づいて$Xを更新します |
VARIABLEと同じ |
|
STREAM:すべての引数を切り捨てなしに記述するか、行終端文字を挿入します。引数の長さを$Xに追加します。 |
VARIABLE ($X=WIDTH) :WIDTH- $X文字まで書き込みます。WRITE ! まで、デバイスに出力を書き込まないようにしてください、または、SET $X は $X をWIDTHより小さくします。 |
|||
READ または WRITE ! |
どちらか |
Write <LF>、$Xを0にセット、$Yをインクリメント |
現在のレコードをWIDTHにするためにPADバイトを書き込みます |
|
WRITE # |
どちらか |
<FF>,<LF>を書き、$Xを0にセットし、$Yをインクリメント |
現在のレコードをWIDTHに、次に<FF>にWIDTH-1 PADバイトを続くようにPADバイトを書き込みます |
|
CLOSE |
どちらか |
書き込みの後、$X>0の場合、<LF>を書き込み |
WRITEの後、$X>0 の場合、暗黙の "WRITE !" を実行します。 完全なレコードを作成するために PADバイトを追加します。後続のPADバイトを回避する必要がある場合は、FIXEDフォーマット・ファイルを閉じる前に $Xを0に設定します。 |
|
READ X |
どちらか |
$X=WIDTH まで、または <LF>またはEOFになるまで文字を返します。<LF>が見つかった場合は、$Xを0にセットし、$Yをインクリメントします。 |
WIDTH 文字を返します; $X と$Y のメンテナンスはありません。ただし、EOFは$Yをインクリメントすることを除外します。 |
|
READ X#len |
どちらか |
最初の $X=WIDTH または len文字までの文字を返すか、<LF>またはEOFに遭遇します; 最大 len文字またはEOFが$Xを更新する場合は、$Xを0にセットし、$Y をインクリメントします。 |
MIN(WIDTH,len) 文字を返します; $Xと$Yのメンテナンスはありません。ただし、EOFは$Yをインクリメントすることを除外します。 |
|
READ *X |
どちらか |
1文字分のコードを返し、$Xをインクリメントします。もし WIDTH=$X または <LF>が見つかった場合は $X=0 にセットし、$Y をインクリメントします;EOFがあった場合、-1を返します。 |
EOFが-1を返す場合、1文字のコードを返します;$Xと$Yのメンテナンスはありません。ただし、EOFは$Yをインクリメントすることを除外します。 |
注意 | |
---|---|
|
バイナリデータファイルを書き込むには、FIXED:WRAP:CHSET="M" で開き、WRITEの前に$Xをゼロに設定して、最後のレコードをスペース(デフォルトのPADバイト値)で埋めないようにします。
注意 | |
---|---|
CHESTが "M"でない場合、FIXEDは異なる定義を持ちます。各レコードは実際にはRECORD SIZEで指定されたバイト数と同じです。パディング・バイトは、必要に応じて各レコードに追加されます。 |
例:
bincpy(inname,outname); GT.M routine to do a binary copy from file named in argument 1 to file named in argument 2 ; new adj,nrec,rsize,x new $etrap set $ecode="",$etrap="goto error",$zstatus="" set rsize=32767 ; max recordsize that keeps $X on track open inname:(readonly:fixed:recordsize=rsize:exception="goto eof") open outname:(newversion:stream:nowrap:chset="M") for nrec=1:1 use inname read x use outname write x eof if $zstatus["IOEOF" do quit . set $ecode="" . close inname . use outname . set adj=$x . set $x=0 close outname . write !,"Copied ",$select((nrec-1)<adj:adj,1:((nrec-1)*rsize)+adj)," bytes from ",inname," to ",outname else use $principal write !,"Error with file ",inname,":" error write !,$zstatus close inname,outname quit
次の表に、関連する領域にグループ化されたシーケンシャル・ファイルのデバイスパラメータの概要を示します。詳細については、 “Open”, “Use”, “Close”を参照してください。
ファイルポインタの位置を決めるデバイスパラメータ | ||
---|---|---|
デバイスパラメータ |
コマンド |
コメント |
APPEND |
O |
EOFにファイルポインタの置きます。 |
REWIND |
O/U/C |
ファイルの開始の位置にファイルポインタを置きます。 |
SEEK=strexpr |
O/U |
現在のファイルポインタを strexpr で指定された場所に移動します。strexpr の形式は "[+|-]integer" 形式の文字列で、符号なし(unsigned)の値はファイルの先頭からのオフセットを指定し、明示的に符号付きの値は現在のファイル位置に対するオフセットを指定します。STREAMまたはVARIABLE形式の場合、符号の後の正の intexpr はバイトオフセットですが、FIXED形式の場合はレコードオフセットです。バイト・オーダー・マーカー(BOM)が存在する可能性に対処するために、UTF文字セットで書かれたFIXEDフォーマットファイルのSEEKは、デバイスが作成されてから少なくとも1つ前のREADに従わなければなりません。 |
ファイルフォーマットのデバイスパラメータ | ||
---|---|---|
デバイスパラメータ |
コマンド |
コメント |
[NO]FIXED |
O |
レコードが固定長であるかどうかを制御 |
[Z]LENGTH=intexpr |
U |
仮想ページの長さを制御 |
RECORDSIZE=intexpr |
O |
レコードサイズの最大を指定 |
STREAM |
O |
ストリームフォーマットを指定 |
VARIABLE |
O |
レコードが可変長であるかどうかを制御 |
[Z]WIDTH=intexpr |
U |
出力ラインの最大幅を制御 |
[Z][NO]WRAP |
O/U |
最大幅より長い出力行のハンドリングを制御 |
ファイルアクセスのデバイスパラメータ | ||
---|---|---|
デバイスパラメータ |
コマンド |
コメント |
DELETE |
C |
CLOSEによる削除されるファイルを指定 |
GROUP=expr |
O/C |
所有者のグループ内の他のユーザのファイルのパーミッションを指定 |
NEWVERSION |
O |
GT.Mがファイルの新しいバージョンを作成することを指定 |
OWNER=expr |
O/C |
ファイルのオーナーのためにファイルのパーミッションを指定 |
[NO]READONLY |
O |
読み取り専用のファイルにアクセスすることを制御 |
RENAME=expr |
C |
CLOSEが式で指定された名前のディスクファイルの名前を置き換えることを指定します。 |
SYSTEM=expr |
O/C |
ファイルのオーナーのためにファイルのパーミッションを指定 |
[NO]TRUNCATE |
O/U |
ファイル内の存在しているデータを上書きする制御 |
UIC=expr |
O/C |
ファイルオーナーのIDを指定 |
WORLD=expr |
O/C |
所有者のグループでは無いユーザのファイルのパーミッションを指定 |
O:OPENコマンドに適用
U:USEコマンドに適用
C:CLOSEコマンドに適用
このセクションでは、GT.Mのシーケンシャルファイル操作のいくつかの解説例があります。
例:
GTM>do ^FREAD FREAD; zprint ^FREAD read "File > ",sd set retry=0 set $ztrap="BADAGAIN" open sd:(readonly:exception="do BADOPEN") use sd:exception="goto EOF" for use sd read x use $principal write x,! EOF; if '$zeof zmessage +$zstatus close sd quit BADOPEN; set retry=retry+1 if retry=2 open sd if retry=4 halt if $piece($zstatus,",",1)=2 do . write !,"The file ",sd," does not exist. Retrying in about 2 seconds ..." . hang 2.1 . quit if $piece($zstatus,",",1)=13 do . write !,"The file ",sd," is not accessible. Retrying in about 3 seconds ..." . hang 3.1 . quit quit BADAGAIN; w !,"BADAGAIN",! File >
この例では、ファイルの名前を尋ね、その内容を表示します。そのファイルをREADONLYとして開き、EXCEPTIONを指定します。OPENの例外ハンドラは、file-not-found および file-access エラーを処理し、エラー時にOPENコマンドを再試行します。1番目のUSE使用は、ファイル終了(end-of-file)を処理するEXCEPTION(例外)を設定します。FORループは1回にファイルの1レコードを読み、プリンシパル(主)デバイスへ各レコードを転送します。EXCEPTIONの中のGOTOは、FORループを終了します。ラベルEOFの地点で、もし$ZEOFがfalseならば、コードはトリガされた例外のそのエラーを再発行します。それ以外の場合、CLOSEはファイルを解放します。
例:
GTM>do ^formatACCT formatACCT; zprint ^formatACCT; set sd="temp.dat",acct="" open sd:newversion use sd:width=132 for set acct=$order(^ACCT(acct)) quit:acct="" do . set rec=$$FORMAT(acct) . write:$y>55 #,hdr write !,rec close sd quit
これは、ファイルtemp.dat のNEWVERSIONをOPENします。FORループは、行をフォーマットし(このコードフラグメントに示されていない)そして、ファイルへそれらを書き込んでいる^ACCTグローバルを介して繰り返します。FORループでは、より管理しやすいブロックに長い行のコードを分割するために、引数なしのDO構文を使用します。このプログラムは、55行ごとにヘッダーレコード(初期化で設定されており、このコードフラグメントには示されていません)を書き込みます。これは、アプリケーションページの長さで、上下の余白が許されるためです。