fopen() — ファイルのオープン

形式

#include <stdio.h>
FILE *fopen(const char *filename, const char *mode);

言語レベル

ANSI

スレッド・セーフ

はい

説明

fopen() 関数は、 filenameで指定されたファイルをオープンします。 mode パラメーターは、そのファイルに要求されたアクセス・タイプを指定する文字ストリングです。 mode 変数には、オプションのキーワード・パラメーターが後に続く、位置パラメーターが 1 つ含まれます。

注: プログラムが SYSIFCOPT (*IFSIO) または SYSIFCOPT (*IFS64IO) でコンパイルされ、 fopen() が統合ファイル・システムにファイルを作成すると、そのファイルの所有者、所有者のグループ、および公用には、そのファイルに対する読み取り、書き込み、および実行権限が与えられます。

ファイル名に期待されるフォーマット:

プログラムがSYSIFCOPT(*IFSIO)またはSYSIFCOPT( *IFS64IO )でコンパイルされている場合、fopen()は統合ファイルシステム"/path/to/stream/file "フォーマットのファイル名を要求します。 プログラムがSYSIFCOPT(*NOIFSIO)でコンパイルされている場合、fopen()は "library/file "形式のファイル名を要求する。SYSIFCOPT(*NOIFSIO)がデフォルトである。
SYSIFCOPT オプションの設定に関係なく、 - API(open、read、write)は、統合ファイル・システム・ストリームに対して動作します - レコードI/Oインターフェース(_Ropen、_Rread、_Rwrite)は、あらゆるデータベース・ファイルに対して動作します。
POSIX

位置パラメーターには次の値が可能です。
モード
説明
r
読み取り用にテキスト・ファイルをオープンする ファイルが存在している必要があります。
w
書き込み用にテキスト・ファイルを作成する。 所定のファイルが存在している場合、それが論理ファイルでない限り、その内容は破棄されます。
a
ファイルの終わりに書き込む付加モードで、テキスト・ファイルをオープンする。 fopen() 関数は、ファイルが存在せず、論理ファイルでない場合にファイルを作成します。
r+
読み取りおよび書き込み用にテキスト・ファイルをオープンする。 ファイルが存在している必要があります。
w+
読み取りおよび書き込み用にテキスト・ファイルを作成する。 所定のファイルが存在している場合、それが論理ファイルでない限り、その内容はクリアされます。
a+
読み取りおよびファイルの終わりでの更新用に、付加モードでテキスト・ファイ ルをオープンする。 fopen() 関数は、ファイルが存在しない場合は作成します。
rb
読み取り用にバイナリー・ファイルをオープンする ファイルが存在している必要があります。
wb
書き込み用に空のバイナリー・ファイルを作成する。 ファイルが存在している場合、それが論理ファイルでない限り、内容はクリアされます。
ab
ファイルの終わりでの書き込み用に、付加モードでバイナリー・ファイルをオー プンする。 fopen 関数は、ファイルが存在していないときにはファイルを作成します。
r+b または rb+
読み取りおよび書き込み用にバイナリー・ファイルをオープンする。 ファイルが存在している必要があります。
w+b または wb+
読み取りおよび書き込み用に空のバイナリー・ファイルを作成する。 ファイルが存在している場合、それが論理ファイルでない限り、その内容はクリアされます。
a+b または ab+
ファイルの終わりでの書き込み用に、付加モードでバイナリー・ファイルをオー プンする。 fopen() 関数は、ファイルが存在しない場合は作成します。
注:
  1. fopen() 関数は、属性 type=record および ab +, rb +, または wb + を使用してオープンされたファイルに対してはサポートされません。
  2. ww+wbw+b、および wb+ パラメーターを使用する場合には注意が必要です。同じ名前の既存ファイルにあるデータは失われます。
テキスト・ファイル には出力可能文字と制御文字が含まれ、これらの文字で行が構成されています。 コンパイラーによっては、おそらく最終行を除き、各行は改行文字で終了します。 システムは出力テキスト・ストリームに制御文字を挿入または変換することができます。 fopen() 機能モード「a」および「a +」は、 QSYS.LIB ファイル・システム。 すべてのモードで、テキスト・ファイル用に QSYS.LIB ファイル・システムを使用する場合には実装制限があります。 ファイルの開始を超えた検索は、テキスト・モードでオープンされたストリームの操作には信頼できません。
注: fopen() を使用して QSYS.LIB ファイル・システムでライブラリー名 *LIBL またはブランクを指定すると、ファイルは QTEMP ライブラリーに作成されます。

テキスト・ファイルが存在していない場合、次のコマンドを使用して作成できます。

CRTSRCPF FILE(MYLIB/MYFILE) RCDLEN(LRECL) MBR(MYMBR) SYSTEM(*FILETYPE)

注: テキスト・ストリームへのデータ出力は、入力上の同じデータとは比較されない場合があります。 QSYS.LIB ファイル・システムはデータベース・ファイルをメンバーのディレクトリーとして扱います。 fopen() 関数を使用してメンバーを動的に作成するには、その前にデータベース・ファイルが存在していなければなりません。

統合ファイル・システムの現行ファイル・システムの制限については、インフォメーション・センターの統合ファイル・システムのトピックにある 大規模ファイルのサポート を参照してください。 2 GB を超える統合ファイル・システムのファイルについては、ご使用のアプリケーションのプログラム・アクセスに 64 ビット C ランタイム関数を許可する必要があります。 次のメソッドを使用してプログラム・アクセスを許可できます。

  • コンパイル・コマンドに SYSIFCOPT(*IFS64IO) を指定します。これにより、ネイティブ C コンパイラーは _IFS64_IO_ を定義します。これにより、マクロ _LARGE_FILES および _LARGE_FILE_API が定義されます。
  • プログラム・ソースで、またはコンパイル・コマンドに DEFINE('_LARGE_FILES') を指定して、マクロ _LARGE_FILES を定義します。 既存の C ランタイム関数およびコード内の関連データ型はすべて自動的に 64 ビット・バージョンにマップされるか、再定義されます。
  • プログラム・ソースで、またはコンパイル・コマンドに DEFINE('_LARGE_FILE_API') を指定して、マクロ _LARGE_FILE_API を定義します。 これにより、新しい 64 ビット C ランタイム関数およびデータ型のセットが見えるようになります。 アプリケーションは使用する C ランタイム関数の名前を、既存バージョンと 64 ビット・バージョンの両方について明示的に指定する必要があります。

64 ビット C ランタイム関数には、 int fgetpos64()FILE *fopen64()FILE *freopen64()FILE *wfopen64()int fsetpos64(FILE *, const fpost64_t *)FILE *tmpfile64()int fseeko(FILE *, off_t, int)int fseeko64(FILE *, off64_t, int)off_t ftello(FILE *)、および off64_t ftello64()が含まれます。

バイナリー・ファイル には、一連の文字が含まれます。 バイナリー・ファイルの場合、システムは入力または出力の制御文字を変換しません。

バイナリー・ファイルが存在していない場合、次のコマンドを使用して作成できます。

CRTPF FILE(MYLIB/MYFILE) RCDLEN(LRECL) MBR(MYMBR) MAXMBRS(*NOMAX) SYSTEM(*FILETYPE)

ファイルを aa+aba+b または ab+ モードでオープンする場合は、すべての書き込み操作はファイルの終わりで行われます。 fseek() 関数または rewind() 関数を使用してファイル・ポインターを位置変更することはできますが、書き込み関数は、操作を実行する前にファイル・ポインターをファイルの終わりに戻します。 このアクションは、既存データへの上書きを防ぐためのものです。

更新モード (2 または 3 番目の位置に + を使用して) を指定す る場合は、ファイルの読み書き両方ができます。 ただし、読み取りと書き込みを切り替える場合は、 fseek()fsetpos()rewind()、または fflush()などの位置決め機能を介在させる必要があります。 出力は、ファイルの終わりが検出された場合に直ちに入力に続くことができます。

非統合ファイル・システムのキーワード・パラメーター

blksize=value
レコードの物理ブロックの最大長をバイトで指定する。
lrecl=value
固定長レコードの長さと、可変長レコードの最大長を、バイトで指定する。
recfm=value
value には、以下の値を指定できます。
F
固定長、非ブロック化レコード
FB
固定長、ブロック化レコード
V
可変長、非ブロック化レコード
VB
可変長、ブロック化レコード
VBS
テープ・ファイル用の可変長で、ブロック化したスパン・レコード
VS
テープ・ファイル用の可変長で、非ブロック化したスパン・レコード
D
テープ・ファイル用 ASCII D 形式の、可変長で、非ブロック化した非スパン・レコード
DB
テープ・ファイル用 ASCII D 形式の、可変長で、ブロック化した非スパン・レコード
U
テープ・ファイルの不定形式
FA
固定長で、出力ファイル用に先頭文字書式制御データを使用
注: ファイルが CTLCHAR (*FCFC) を使用して作成された場合は、最初の文字の用紙制御が使用されます。 ファイルが CTLCHAR(*NONE) を使用して作成されている場合、先頭文字書式制御は使用されません。
commit=value
value には、以下の値を指定できます。

N このパラメーターは、このファイルがコミットメント制御下でオープンされないことを識別します。 これはデフォルト値。

Y このパラメーターは、このファイルがコミットメント制御下でオープンされることを識別します。

ccsid=value
オペレーティング・システムでサポートされていない CCSID が指定された場合、これはデータ管理によって無視されます。

コンパイル・コマンドに LOCALETYPE(*LOCALEUTF) が指定された場合は、デフォルト値は LC_CTYPE CCSID の値です。これは、現行ロケール設定によって決まります。 ロケール設定の詳細については、 setlocale ()-ロケールの設定 を参照してください。 コンパイル・コマンドに LOCALETYPE(*LOCALEUTF) が指定されていない場合、デフォルト値はジョブの CCSID の値です。 ファイル CCSID 値の詳細については、 ファイル CCSID を参照してください。

arrseq=value
value は以下のいずれかです。

N このパラメーターは、ファイルが作成された方法で、このファイルが処理されていることを識別します。 これはデフォルト値。

Y このパラメーターは、このファイルが到着順で処理されることを識別します。

indicators=value
value には、以下の値を指定できます。

N この値は、ディスプレイ、ICF、またはプリンター・ファイルの標識がファイル・バッファーに格納されていることを識別します。 これはデフォルト値。

Y このパラメーターは、ディスプレイ、ICF、またはプリンター・ファイルの標識が、ファイル・バッファーではなく、別の標識領域に格納されていることを識別します。 ファイル・バッファーは、書き込みと読み込みのときにシステムがユーザー・プログラムとオペレーション・システム間でデータを転送するために使用する領域です。 ICF ファイルを処理する場合には標識を別の標識領域に格納する必要があります。

type=value
value には、以下の値を指定できます。

memory このパラメーターは、C プログラムからのみ使用できるメモリー・ファイルとして、このファイルを識別します。 これはデフォルト値。

レコード このパラメーターは、順次レコード入出力用にファイルがオープンされる様に指定します。 ファイルはバイナリー・ファイルとしてオープンする必要があります。そうしないと、 fopen() 関数は失敗します。 読み取り操作と書き込み操作は、 fread() 関数と fwrite() 関数を使用して行われます。

統合ファイル・システムのキーワード・パラメーター

type=value
value には、以下の値を指定できます。

レコード ファイルは、順次レコード入出力用にオープンされています。 (ファイルは、バイナリー・ストリームとしてオープンする必要があります。)

ccsid=value
ccsid はコード・ページ値に変換されます。 デフォルトとして、コード・ページとしてジョブ CCSID の値を使用します。 CCSID とコード・ページ・オプションの両方を指定することはできません。 CCSID オプションは、オペレーティング・システムおよびデータ管理ベースのストリーム入出力との互換性を提供します。
注: 混合データ (データに 1 バイト文字と 2 バイト文字の両方が含まれる) は、テキストのファイル・データ処理モードではサポートされません。 混合データは、バイナリーのファイル処理モードでサポートされています。

ccsid キーワードを指定する場合は、o_ccsid キーワードやコード・ページ・キーワードを指定できません。

変換されたデータが拡大したり縮小する可能性があるため、データ・サイズや現行のファイル・オフセットを推測することは危険です。 例えば、100 バイトの物理サイズを持つファイルで、アプリケーションがファイルから 100 バイトを読み取った後のファイル・オフセットは 50 しかない場合があります。 含まれている CCSID によっては、ファイル全体を読み取るために、アプリケーションが 200 バイト以上を読み取る必要がある場合があります。 したがって、 ftell()fseek()fgetpos()、および fsetpos()などのファイル位置決め機能が動作しない可能性があります。 これらの関数はエラー ENOTSUP が発生して失敗します。 関数の読み取りは、デフォルトのように、バッファリングがオンの場合にも機能しません。 バッファリングをオフにするには、_IONBF キーワードを指定して setvbuf 関数を使用します。

以下の 3 つの条件がすべて発生すると、 fopen() 機能は ECONVERT エラーで失敗する可能性があります。
  • ファイル・データ処理モードがテキストである。
  • コード・ページが指定されていない。
  • ジョブの CCSID が「混合データ」(1 バイト文字と 2 バイト文字の両方が含まれているデータ) である。
o_ccsid=value

コンパイル・コマンドに LOCALETYPE(*LOCALEUTF) が指定された場合は、デフォルト値は LC_CTYPE CCSID の値です。これは、現行ロケール設定によって決まります。 ロケール設定の詳細については、 setlocale ()-ロケールの設定 を参照してください。 コンパイル・コマンドに LOCALETYPE(*LOCALEUTF) が指定されていない場合、デフォルト値はジョブの CCSID の値です。 ファイル CCSID 値の詳細については、 ファイル CCSID を参照してください。

このパラメーターは、指定された値がコード・ページに変換されない点を除き、 ccsid パラメーターと類似しています。 また、混合データもサポートされています。 ファイルが作成されると、指定された CCSID でタグ付けされます。 ファイルがすでに存在している場合、データは読み取り操作時に、ファイルの CCSID から指定された CCSID に変換されます。 書き込み操作では、データは指定された CCSID にあると仮定され、ファイルの CCSID に変換されます。

変換されたデータが拡大したり縮小する可能性があるため、データ・サイズや現行のファイル・オフセットを推測することは危険です。 例えば、100 バイトの物理サイズを持つファイルで、アプリケーションがファイルから 100 バイトを読み取った後のファイル・オフセットは 50 しかない場合があります。 含まれている CCSID によっては、ファイル全体を読み取るために、アプリケーションが 200 バイト以上を読み取る必要がある場合があります。 したがって、 ftell()fseek()fgetpos()、および fsetpos() などのファイル位置決め機能は作動しません。 これらの関数は、ENOTSUP を発生して失敗します。 関数の読み取りは、デフォルトのように、バッファリングがオンの場合にも機能しません。 バッファリングをオフにするには、_IONBF キーワードを指定して setvbuf 関数を使用します。

o_ccsid を使用する例

/* Create a file that is tagged with CCSID 37 */
if ((fp = fopen("/MYFILE" , "w, o_ccsid=37")) == NULL) {
   printf("Failed to open file with o_ccsid=37\n");
}

fclose(fp);

/* Now reopen the file with CCSID 13488, because your application
 wants to deal with the data in UNICODE */

if ((fp = fopen("/MYFILE" , "r+, o_ccsid=13488")) == NULL) {
   printf("Failed to open file with o_ccsid=13488\n");
}
/* Turn buffering off because read functions do not work when
buffering is on */

if (setbuf(fp, NULL, _IONBF, 0) != 0){
    printf("Unable to turn buffering off\n");
}
/* Because you opened with o_ccsid = 13488, you must provide
all input data as unicode.
If this program is compiled with LOCALETYPE(*LOCALEUCS2),
L constrants will be unicode. */

funcreturn = fputws(L"ABC", fp); /* Write a unicode ABC to the file. */

if (funcreturn < 0) {
   printf("Error with 'fputws' on line %d\n", __LINE__);
}
/* Because the file was tagged with CCSID 37, the unicode ABC was
converted to EBCDIC ABC when it was written to the file. */
codepage=value
value により指定されるコード・ページが使用されます。

コード・ページ・キーワードを指定する場合は、ccsid キーワードや o_ccsid キーワードは指定できません。

オープンするファイルが存在しておらず、オープン・モードでファイルを作成するように指定した場合は、ファイルが作成されて計算されたコード・ページでタグ付けされます。 ファイルがすでに存在している場合は、ファイルから読み取られるデータがファイル・コード・ページから計算されたコード・ページに、読み取り操作中に変換されます。 ファイルに書き込まれるデータは、計算されたコード・ページにあり、書き込み操作中にファイルのコード・ページに変換されると仮定されます。

crln=value
value には、以下の値を指定できます。

Y 使用される行の終了文字は、復帰改行文字 [CR] と改行文字 [NL] の組み合わせです。 データが読み取られるときに、復帰改行文字 [CR] が string 関数のためにストリップされます。 データがファイルに書き込まれるときには、復帰改行文字 [CR] がそれぞれの改行文字 [NL] の前に追加されます。 行の終了文字処理は、ファイルがテキスト・モードでオープンされている場合にのみ発生します。 これはデフォルト値。

N 使用される行の終了文字は、改行文字 [NL] のみです。

キーワード・パラメーターは大文字と小文字の区別がなく、コンマで区切ります。

パラメーターが一致しない場合、通常 fopen() 関数は失敗します。

戻り値

fopen() 関数は、オープン・ファイルにアクセスするために使用できる FILE 構造体タイプへのポインターを戻します。
注: レコード入出力関数でストリーム・ファイル (タイプ = レコード) を使用するには、 FILE ポインターを RFILE ポインターにキャストする必要があります。

NULL ポインターの戻り値は、エラーを示します。

errno の値は、次のいずれかに設定されます。
意味
EBADMODE
指定されたファイル・モードが無効です。
EBADNAME
指定されたファイル名が無効です。
ECONEVRT
変換エラー。
ENOENT
ファイルまたはライブラリーがありません。
ENOMEM
記憶域割り振り要求が正常に実行されなかった。
ENOTOPEN
ファイルはオープンされていません。
EIOERROR
回復不能入出力エラーが起こりました。
EIORECERR
回復可能入出力エラーが起こりました。
ESCANFAILURE
ファイルは走査失敗のマークを付けられました。

fopen() に渡されたモード・ストリングが正しい場合、ファイル・タイプに関係なく、 fopen() は errno を EBADMODE に設定しません。

fopen() に渡されたモード・ストリングが有効でない場合、ファイル・タイプに関係なく、 fopen() は errno を EBADMODE に設定します。

fopen() に渡されたモード・ストリングが正しいが、その特定タイプのファイルに対して無効である場合、 fopen() は、ファイル・タイプに関係なく、errno を ENOTOPEN、EIOERROR、または EIORECERR に設定します。

この例は、読み取り用ファイルのオープンを試行します。
#include <stdio.h>
#define  MAX_LEN  60
 
int main(void)
{
   FILE *stream;
   fpos_t pos;
   char line1[MAX_LEN];
   char line2[MAX_LEN];
   char *result;
   char ch;
   int num;
 
   /* The following call opens a text file for reading.   */
   if ((stream = fopen("mylib/myfile", "r")) == NULL)
      printf("Could not open data file\n");
   else if ((result = fgets(line1,MAX_LEN,stream)) != NULL)
           {
            printf("The string read from myfile: %s\n", result);
            fclose(stream);
           }
 
   /* The following call opens a fixed record length file */
   /* for reading and writing.                            */
   if ((stream = fopen("mylib/myfile2", "rb+, lrecl=80,  \
                 blksize=240, recfm=f")) == NULL)
         printf("Could not open data file\n");
   else {
         fgetpos(stream, &pos);
         if (!fread(line2,sizeof(line2),1,stream))
            perror("fread error");
         else printf("1st record read from myfile2: %s\n", line2);
 
         fsetpos(stream, &pos);     /* Reset pointer to start of file */
         fputs(result, stream);     /* The line read from myfile is   */
                                    /* written to myfile2.            */
         fclose(stream);
        }
}

関連情報