FILEBUF(3CC4)

名前
filebuf - ファイル入出力用バッファクラス

形式

#include <fstream.h>

typedef long streampos;
typedef long streamoff;

class ios : virtual public unsafe_ios, public stream_MT {
public:
        enum open_mode  {
            in       = 0x01,	// 読み取り用にオープン
            out      = 0x02,	// 書き込み用にオープン
            ate      = 0x04,	// EOF までシークする
            app      = 0x08,	// 追加モード: EOF 以降に追加
            trunc    = 0x10,	// ファイルがあれば内容をクリア
            nocreate = 0x20,	// ファイルがなければオープンを失敗させる
            noreplace= 0x40	// ファイルがあればオープンを失敗させる
        };
        enum seek_dir { beg=0, cur=1, end=2 };
        // 残りの部分については、ios(3CC4) を参照 ...
};

class filebuf : public streambuf {
public:
        static const int openprot ; /* オープンに対するデフォルトの保護 */
                        filebuf() ;
                        ~filebuf() ;
                        filebuf(int f);
                        filebuf(int f, char*  p, int len) ;
        filebuf*        attach(int f) ;
        filebuf*        attach_unlocked(int);
        filebuf*        close();
        filebuf*        close_unlocked();
        int             detach() ;
        int             detach_unlocked();
        int             fd();
        int             is_open();
        int             is_open_unlocked();
        filebuf*        open(char *name, int omode, int prot=openprot) ;
        filebuf*        open_unlocked(const char*, int, int=filebuf::openprot);
        streampos       seekoff(streamoff, seek_dir, int omode) ;
        streampos       seekpos(streampos, int omode) ;
        streambuf*      setbuf(char* p, int len) ;
        int             sync() ;
};

機能説明

クラス filebuf は、文字の入力元または出力先としてファイルを 使用するように特殊化した streambuf です。 文字はファイルからフェッチ (入力) され、 ファイルによって消費され (ファイルに書き込まれ) ます。 filebuf がオープンファイルに 接続 ( アタッチ ) されているとき、 その filebuf は「オープンしている」といいます。 一方、オープンファイルに接続されていないとき、 filebuf はクローズしていることになります。 デフォルトでは、ファイルは 保護モード filebuf::openprot (0666) でオープンされます。

アタッチされているファイルがシーク可能なとき、 filebuf ではシーク操作が可能です。 たとえば、通常のディスクファイルはシーク可能ですが、 端末はシークできません。 アタッチされたファイルで読み取り (書き込み) が可能な場合は、 filebuf でフェッチ (格納) が可能です。 たとえば、標準入力では読み取りだけが可能で、 標準出力では書き込みだけが可能です。 C の標準入出力 (stdio) とは異なり、 同じ filebuf に対する入力操作と出力操作の間でシークは不要です。 初期設定では 4 文字の書き戻しが可能です。

streambuf の基本的な操作については sbufprot(3CC4) および sbufpub(3CC4) で説明します。 バッファ領域は、コンストラクタに与えられていない場合は 自動的に割り当てられます。 また、 setbuf の呼び出しにより明示的に 割り当てられます (通常、 setbuf の呼び出しが使用されます)。 filebuf をバッファリングしないようにすると、 入力または出力の対象となる各文字に対してシステムコールが必要になります。 入力ポインタと出力ポインタは概念的には統合されていて、 1 つのポインタとして動作します。

filebuf は、UNIX のファイル記述子 (システムコールで 渡される小さな整数) を介してファイルを操作します。 C の標準入出力は使用されません。 提供されているファイル記述子については、 妥当性検査を行わないので注意してください。

いくつかのメンバー関数には 2 種類の定義が行われています。 1 つは unsafe (マルチスレッド環境で使用できない) バージョン ( 接尾辞 "_unlocked"を持つもの) で、 複数のスレッドからのアクセスに対して保護されていません。 もう 1 つは、safe バージョン (デフォルト) で、 mutex ロックを使用して 複数のスレッドからの同時アクセスに対する保護を行います。

filebuf() クローズした filebuf を作成します。

filebuf(f)
    ファイル記述子 f にアタッチされた、オープンしている filebuf を作成します。

filebuf(f, p, len)
    ファイル記述子 f にアタッチされた、 オープンしている filebuf を作成します。 このファイル記述子はオープンしていると想定されます。 初期のバッファ領域として p で始まる len 文字の char 配列が 使用されます。 p がゼロ、または len がゼロ以下のとき、 filebuf でバッファリングは行われません。

  メンバー関数

filebuf* fb = fbuf.attach(f)
    fbuf がクローズしているとき、 それをファイル記述子 f (オープンしていると想定) にアタッチし、 fbuf のアドレスを返します。 fbuf がすでにオープンしている場合は f を 無視してゼロを返します。 このメンバーは MT-safe です。

filebuf *fb = fbuf.attach_unlocked(f)
    機能的には attach と同じですが、mutex ロックをいっさい行わないため、 MT-safe ではありません。

int i = fbuf.detach()
    ファイル記述子に対応づけられているファイルへの待機中の出力をフラッシュし、 f からファイル記述子を切り離します。 ファイル記述子を返します。 アタッチされているファイル記述子を close() によって クローズさせたくない場合は、 close() の前にこの関数を呼び出してください。このメンバーは MT-safe です。

int i = fbuf.detach_unlocked()
    機能的には detach と同じですが、mutex ロックをいっさい行わないため、 MT-safe ではありません。

filebuf* fb = fbuf.close()
    保留中の出力をフラッシュし、ファイル記述子を無条件にクローズし、 fbuf をクローズします。 戻り値は、エラー時にはゼロ、正常終了時には fbuf となります。 このメンバーは MT-safe です。

filebuf* fb = fbuf.close_unlocked()
    機能的には close と同じですが、mutex ロックをいっさい行わないため、 MT-safe ではありません。

int f = fbuf.fd()
    fbuf にアタッチされているファイル記述子を返します。 fbuf がオープンしていない場合は EOF を返します。

int i = fbuf.is_open()
    fbuf がオープンしていれば (ファイル記述子に 接続されていれば) ゼロ以外の値、 オープンしていない場合はゼロを返します。 このメンバーは MT-safe です。

int i = fbuf.is_open_unlocked()
    機能的には is_open と同じですが、mutex 相互排他ロックをいっさい行わないため、 MT-safe ではありません。

filebuf* fb = fbuf.open(name, mode, prot)
    fbuf がまだオープンしていない場合は、 ファイル name をオープンし、 そのファイル記述子を fbuf に接続します。 fbuf がオープンしている場合はエラーになります。 ファイルが存在せず、かつ mode に ios::nocreate が セットされていない場合は、 prot で指定された保護ビット (デフォルト値は 0666) で ファイルを作成しようとします。 mode パラメタは、 fstream(3CC4) で説明されている ios::open_mode のビットの集まりです。 これらのビットの論理和をとることができます。 この関数の戻り値は、正常終了時には fbuf のアドレス、 何らかの異常があった場合はゼロになります。 このメンバーは MT-safe です。

filebuf* fb = fbuf.open_unlocked(name, mode, prot)
    機能的には open と同じですが、mutex 相互排他ロックをいっさい行わないので MT-safe では ありません。

streampos pos2 = fbuf.seekoff(off, dir, mode)
    sbufpub(3CC4) で説明しているように、 off と dir により、入力ポインタと出力ポインタの一方または両方の位置を変更します。 ただし、 mode パラメタは無視します。 fbuf がオープンしていない、 アタッチされたファイルがシークをサポートしていない、 シークをサポートしていても実行できない (ファイルの先頭または終端 を越える) のいずれかの場合は異常終了します。 off は、ファイル内の dir によって指定された位置からのオフセットです。 戻り値は、正常終了時にはファイルの新しい位置、 異常終了時には EOF になります。 エラー時のファイルの位置は未定義です。

streampos pos2 = fbuf.seekpos(pos, mode)
    fbuf.seekoff((streamoff)pos, ios::beg, mode) の呼び出しと等価です。 pos の値は、 seekoff または seekpos を あらかじめ呼び出して取得したもの、 またはファイルの先頭を表すゼロでなければなりません。 sbufpub(3CC4) も参照してください。

streambuf* sb = fbuf.setbuf(p, len)
    fbuf がオープンしていて、バッファ領域が割り当てられていれば、 setbuf は何も変更を行わずにゼロを返します。 それ以外の場合、 p が指す位置から始まる len 文字の長さの char 配列を 新しいバッファ領域として割り当てます。 このときの戻り値は fbuf のアドレスです。 p がゼロ、または len がゼロ以下のとき、 バッファ領域は割り当てられず、 fbuf でバッファリングは行われません。

int i = fbuf.sync()
    入力 / 出力ポインタをアタッチされたファイルの実際の位置と 一致させるように試みます。 これにより、まだ書き込まれていない文字をフラッシュしたり、 すでに入力された文字の上にファイルをバックアップすることがあります。 戻り値は、正常終了時にはゼロ、 エラー時には EOF になります。

    文字のグループをファイルに書き込むときに、 そのグループを構成するすべての文字が同時に書き込まれることを 確実にするためには、 割り当てるバッファ領域のサイズを最大のグループよりも大きくし、 文字を格納する直前に sync を実行し、 文字を格納した直後にもう一度 sync を実行してください。

関連項目

ios.intro(3CC4)、 fstream(3CC4)、 ios(3CC4)、 sbufprot(3CC4)、 sbufpub(3CC4)、 stream_locker(3CC4)、 stream_MT(3CC4)、 『C++ ライブラリ・リファレンス』の第 3 章「従来型の iostream ライブラリ」および 第 4 章「マルチスレッド環境での従来型の iostream ライブラリの使用」

警告

通常、UNIX はシークの異常を報告しません。 したがって、 filebuf も報告しません。