HP C RTL とリンクする方法,および HP C 関数とマクロを呼び出す方法を学習したら,次に主要な目的である入出力 (I/O) のために HP C RTL を使用できるようになります。
システムごとに I/O の方法は異なっているため, OpenVMS 固有のファイル・アクセス方式を十分理解しておくことが必要です。十分理解しておけば,ソース・プログラムをあるオペレーティング・システムから別のオペレーティング・システムに移植するときに,機能上の相違点をあらかじめ予測することができます。
図 1-3 は, HP C RTL で使用できる I/O 方式を示しています。 OpenVMS システム・サービスは OpenVMS オペレーティング・システムと直接通信するため,オペレーティング・システムに最も近い位置にあります。 OpenVMS RMS (Record Management Services) 関数はシステム・サービスを使用し,それらのシステム・サービスがオペレーティング・システムを操作します。 HP C の標準 I/O および UNIX I/O 関数とマクロでは, RMS 関数を使用します。 HP C RTL 標準 I/O および UNIX I/O 関数およびマクロは,システムを操作するまでに複数の関数呼び出しのレイヤを通過しなければならないため,オペレーティング・システムから最も遠い位置にあります。
図 1-3 C プログラムからの I/O インタフェース
C プログラミング言語は UNIX オペレーティング・システムで開発されており,標準 I/O 関数は,ほとんどのアプリケーションで十分効率よく強力で便利な I/O 方式を提供できるように設計されており,さらに C 言語コンパイラが稼動するどのシステムでも関数を使用できるように,移植可能になるように設計されています。
HP C RTL では,このもともとの仕様にさらに機能が追加されています。 HP C RTL で実装されている標準 I/O 関数は,行区切り文字を認識するので, HP C RTL の標準 I/O 関数は特に,テキスト操作の場合に便利です。 HP C RTL では,一部の標準 I/O 関数はプリプロセッサ定義マクロとして実装されています。
同様に,UNIX の I/O 関数はもともと, UNIX オペレーティング・システムにより直接的にアクセス可能になるように設計されています。これらの関数では,数値のファイル記述子を使用してファイルを表現します。 UNIX システムでは,統一されたアクセス方式を可能にするために,すべての周辺デバイスがファイルとして表現されます。
HP C RTL では,もともとの仕様にさらに機能が追加されています。 HP C で実装されている UNIX I/O 関数は,特にバイナリ・データを操作するのに便利です。 HP C RTL ではまた,一部の I/O 関数はプリプロセッサ定義マクロとして実装されています。
HP C RTL には,すべての C コンパイラにある標準 I/O 関数が用意されており,その他にできるだけ多くの他の C の実装と互換性を維持するために UNIX I/O 関数も用意されています。しかし,標準 I/O と UNIX I/O のどちらも,ファイルにアクセスするために RMS を使用します。標準 I/O 関数と UNIX I/O 関数が RMS でフォーマットされたファイルを操作する方法を理解するには,RMS の基礎を学習する必要があります。 RMS ファイルに関連する標準 I/O と UNIX I/O の詳細については, 第 1.7.1 項 を参照してください。 RMS の概要については,『Guide to OpenVMS File Applications』を参照してください。
どの方法が適切であるかを判断する前に,まず,「UNIX との互換性が重要なのか, OpenVMS オペレーティング・システムのもとで単独に動作するコードを開発するのが重要なのか」という問題について検討してください。
- UNIX との互換性が重要である場合は,最高レベルの I/O,つまり標準 I/O と UNIX I/O を使用することが必要でしょう。なぜなら,このレベルはオペレーティング・システムからの独立性がかなり高いからです。また,最高レベルの I/O は学習するのも簡単です。初心者のプログラマの場合,このことは重要な要素です。
- UNIX との互換性が重要でない場合や,標準 I/O および UNIX I/O 方式で提供されない高度なファイル処理が必要な場合は, RMS を使用することが望ましいでしょう。
システム・レベルのソフトウェアを開発する場合,システム・サービスへの呼び出しを使用して OpenVMS オペレーティング・システムに直接アクセスしなければならないことがあります。たとえば,$QIO (Queue I/O Request) システム・サービスを通じて,直接ユーザ作成デバイス・ドライバにアクセスしなければならないことがあります。この場合は,OpenVMS レベルの I/O を使用します。経験の豊富な OpenVMS プログラマの場合は,このレベルを推奨します。 OpenVMS システム・サービスを呼び出すプログラムの例については,『HP C User's Guide for OpenVMS Systems』を参照してください。
おそらく, RMS や OpenVMS システム・サービスを使用しないこともあるでしょう。多くのアプリケーションでは,標準 I/O 関数と UNIX I/O 関数が十分効率的に機能します。 図 1-4 は,標準 I/O 関数および UNIX I/O 関数と RMS の依存関係を示しており,使用できるさまざまな I/O 方式も示しています。
図 1-4 標準 I/O および UNIX I/O と RMS の対応関係
1.7.1 RMS のレコード・フォーマットとファイル・フォーマット |
|
標準 I/O および UNIX I/O の関数とマクロの機能および制約事項を理解するには, OpenVMS RMS (Record Management Services) について理解する必要があります。
RMS では次のファイル編成がサポートされます。
順編成ファイルにはレコードが連続的に記録され,レコードとレコードの間に空のレコードは存在しません。相対編成ファイルには固定長のセルが記録され,各セルにはレコードが格納されていることも,格納されていないこともあります。索引順編成ファイルには,データ,キャリッジ制御情報,さまざまなアクセス順序を可能にするキーを格納したレコードが記録されます。
HP C RTL の関数は順編成ファイルにだけアクセスできます。他のファイル編成を使用する場合は,RMS 関数を使用する必要があります。 RMS 関数の詳細については,『HP C User's Guide for OpenVMS Systems』を参照してください。
RMS はレコードの内容を考慮せず,レコードのフォーマットを考慮します。レコードのフォーマットとは,記憶媒体の記録面にレコードが物理的に記録される方法です。
RMS では次のレコード・フォーマットがサポートされます。
- 固定長
- 可変長
- 固定長制御部付可変長 (VFC)
- ストリーム
固定長レコード・フォーマットはファイルの作成時に指定できます。このフォーマットでは,すべてのレコードがファイル内で同じサイズの領域を使用します。ファイルの作成後にレコード・フォーマットを変更することはできません。
可変長,VFC,ストリーム・ファイル・フォーマットのレコードの長さは,最大サイズまでの範囲で変化することができ,最大サイズはファイルの作成時に指定しなければなりません。可変長レコードまたは VFC フォーマットのファイルでは,レコードのサイズはデータ・レコードの先頭にあるヘッダ・セクションに格納されます。ストリーム・ファイルでは,キャリッジ制御文字やライン・フィード文字など,特定の文字が検出されたときに,RMS はレコードを終了します。ストリーム・ファイルはテキストを格納するのに便利です。
RMS では,ファイル内のレコードのキャリッジ制御属性を指定できます。このような属性としては,暗黙のキャリッジ・リターンや Fortran でフォーマットされたレコードがあります。ファイルを端末やライン・プリンタ,他のデバイスに出力するときに, RMS はこれらのキャリッジ制御を解釈します。キャリッジ制御情報はデータ・レコードに格納されません。
デフォルト設定では,ファイルの前のバージョンが存在する場合,ファイルは RMS レコード・フォーマット,最大レコード・サイズ,レコード属性を前のバージョンから継承します。 OpenVMS システム・プログラマの場合,継承された属性は FAB$B_RFM,FAB$W_MRS,FAB$B_RAT と呼びます。前のバージョンが存在しない場合,新たに作成されたファイルのデフォルトはストリーム・フォーマットになり,レコードの終端はライン・フィード・レコード区切り文字および暗黙のキャリッジ・リターン属性で決定されます ( 本書では,この種のファイルをストリーム・ファイルと呼びます )。ストリーム・ファイルは, HP C RTL の標準 I/O および UNIX I/O 関数を使用して操作することができます。これらのファイルや,キャリッジ制御を含まない固定長レコード・ファイルを使用する場合,
fseek関数や
lseek関数を使用して,ファイルのランダムなバイトまでシークする機能に制限はありません。しかし,可変長レコード・フォーマットなど,ファイルに他の RMS レコード・フォーマットのいずれかが含まれる場合は, RMS の制限により,これらの関数はレコード境界までしかシークできません。他の VAX 言語やユーティリティで使用するファイルを作成またはアクセスしなければならない場合を除き,デフォルトの VAX ストリーム・フォーマットを使用してください。
1.7.2 RMS ファイルへのアクセス |
|
RMS の順編成ファイルはレコード・モードまたはストリーム・モードでオープンすることができます。デフォルト設定では,STREAM_LF ファイルはストリーム・モードでオープンされます。他のすべてのファイル・タイプはレコード・モードでオープンされます。ファイルをオープンするときに,省略可能な引数 "ctx=rec" を指定することで,これらのデフォルト設定をレコード・モードに変更したり, "ctx=stm" を指定することでストリーム・モードに設定することができます。 RMS の相対編成ファイルと索引順編成ファイルは常にレコード・モードでオープンされます。アクセス・モードによって, HP C RTL でのさまざまな I/O 関数の動作が決定されます。
RMS で定義されているファイル・タイプの 1 つに, RMS-11 ストリーム・フォーマット・ファイルがあります。このファイル・タイプは,レコード・フォーマットの FAB$C_STM の値に対応します。このフォーマットは,SYS$GET が各レコードから先頭のヌル・バイトを削除する RMS レコード操作として定義されています。このファイル・タイプは HP C RTL によってレコード・モードで処理されるため,明示的に "ctx=stm" を指定してオープンしない限り,バイナリ・データのファイル・フォーマットとしては不適切です。 "ctx=stm" を指定した場合は,ファイルのデータ・バイトがそのまま返されます。
| 注意
OpenVMS Version 7.0 で,ストリーム・ファイルの LRL のデフォルト値は 0 から 32767 に変更されました。この変更により,ソートなどの特定のファイル操作で性能が著しく低下しました。
しかし,この問題は回避することができます。 HP C RTL では,論理名 DECC$DEFAULT_LRL を定義することで,ストリーム・ファイルのレコード長のデフォルト値を変更できるようになりました。
HP C RTL は最初にこの論理名を検索します。この論理名が検索され,0〜32767 の範囲の数値に変換されると,その値がデフォルト LRL として使用されます。
OpenVMS Version 7.0 より前の動作に戻すには,次のコマンドを入力します。
$ DEFINE DECC$DEFAULT_LRL 0
|
|