basic_filebuf 类

描述对 Char_T 类型的元素(其字符特征由类 Tr 确定)与外部文件中存储的元素序列之间的来回传输进行控制的流缓冲区。

语法

template <class Char_T, class Tr = char_traits<Char_T>>
class basic_filebuf : public basic_streambuf<Char_T, Tr>

参数

Char_T
文件缓冲区的基本元素。

Tr
文件缓冲区的基本元素的特征(通常是 char_traits<Char_T>)。

注解

该类模板描述对 Char_T 类型的元素(其字符特征由类 Tr 确定)与外部文件中存储的元素序列之间的来回传输进行控制的流缓冲区。

注意

basic_filebuf 类型的对象是使用 char* 类型的内部缓冲区创建的(不考虑由类型参数 Char_T 指定的 char_type。 这意味着,Unicode 字符串(包含 wchar_t 字符)会在写入内部缓冲区之前转换为 ANSI 字符串(包含 char 字符)。 若要在缓冲区中存储 Unicode 字符串,请创建一个 wchar_t 类型的新缓冲区,并使用 basic_streambuf::pubsetbuf() 方法设置它。 若要查看演示此行为的示例,请参阅下面的内容。

basic_filebuf<Char_T, Tr> 的对象会存储文件指针,它指定的 FILE 对象控制与打开的文件关联的流。 另外,它还存储指向两个文件转换方面的指针,以供受保护的成员函数 overflowunderflow 使用。 有关详细信息,请参阅 basic_filebuf::open

示例

下面的示例演示如何通过调用 pubsetbuf() 方法来强制 basic_filebuf<wchar_t> 类型的对象将 Unicode 字符存储在其内部缓冲区中。

// unicode_basic_filebuf.cpp
// compile with: /EHsc

#include <iostream>
#include <string>
#include <fstream>
#include <iomanip>
#include <memory.h>
#include <string.h>

#define IBUFSIZE 16

using namespace std;

void hexdump(const string& filename);

int main()
{
    wchar_t* wszHello = L"Hello World";
    wchar_t wBuffer[128];

    basic_filebuf<wchar_t> wOutFile;

    // Open a file, wcHello.txt, then write to it, then dump the
    // file's contents in hex
    wOutFile.open("wcHello.txt",
        ios_base::out | ios_base::trunc | ios_base::binary);
    if(!wOutFile.is_open())
    {
        cout << "Error Opening wcHello.txt\n";
        return -1;
    }
    wOutFile.sputn(wszHello, (streamsize)wcslen(wszHello));
    wOutFile.close();
    cout << "Hex Dump of wcHello.txt - note that output is ANSI chars:\n";
    hexdump(string("wcHello.txt"));

    // Open a file, wwHello.txt, then set the internal buffer of
    // the basic_filebuf object to be of type wchar_t, then write
    // to the file and dump the file's contents in hex
    wOutFile.open("wwHello.txt",
        ios_base::out | ios_base::trunc | ios_base::binary);
    if(!wOutFile.is_open())
    {
        cout << "Error Opening wwHello.txt\n";
        return -1;
    }
    wOutFile.pubsetbuf(wBuffer, (streamsize)128);
    wOutFile.sputn(wszHello, (streamsize)wcslen(wszHello));
    wOutFile.close();
    cout << "\nHex Dump of wwHello.txt - note that output is wchar_t chars:\n";
    hexdump(string("wwHello.txt"));

    return 0;
}

// dump contents of filename to stdout in hex
void hexdump(const string& filename)
{
    fstream ifile(filename.c_str(),
        ios_base::in | ios_base::binary);
    char *ibuff = new char[IBUFSIZE];
    char *obuff = new char[(IBUFSIZE*2)+1];
    int i;

    if(!ifile.is_open())
    {
        cout << "Cannot Open " << filename.c_str()
             << " for reading\n";
        return;
    }
    if(!ibuff || !obuff)
    {
        cout << "Cannot Allocate buffers\n";
        ifile.close();
        return;
    }

    while(!ifile.eof())
    {
        memset(obuff,0,(IBUFSIZE*2)+1);
        memset(ibuff,0,IBUFSIZE);
        ifile.read(ibuff,IBUFSIZE);

        // corner case where file is exactly a multiple of
        // 16 bytes in length
        if(ibuff[0] == 0 && ifile.eof())
            break;

        for(i = 0; i < IBUFSIZE; i++)
        {
            if(ibuff[i] >= ' ')
                obuff[i] = ibuff[i];
            else
                obuff[i] = '.';

            cout << setfill('0') << setw(2) << hex
                 << (int)ibuff[i] << ' ';
        }
        cout << "  " << obuff << endl;
    }
    ifile.close();
}
Hex Dump of wcHello.txt - note that output is ANSI chars:
48 65 6c 6c 6f 20 57 6f 72 6c 64 00 00 00 00 00   Hello World.....

Hex Dump of wwHello.txt - note that output is wchar_t chars:
48 00 65 00 6c 00 6c 00 6f 00 20 00 57 00 6f 00   H.e.l.l.o. .W.o.
72 00 6c 00 64 00 00 00 00 00 00 00 00 00 00 00   r.l.d...........

构造函数

构造函数 说明
basic_filebuf 构造 basic_filebuf 类型的对象。

Typedef

类型名称 说明
char_type 将类型名与 Char_T 模板参数关联。
int_type 使 basic_filebuf 范围中的此类型等效于 Tr 范围中具有相同名称的类型。
off_type 使 basic_filebuf 范围中的此类型等效于 Tr 范围中具有相同名称的类型。
pos_type 使 basic_filebuf 范围中的此类型等效于 Tr 范围中具有相同名称的类型。
traits_type 将类型名与 Tr 模板参数关联。

成员函数

成员函数 说明
close 关闭文件。
is_open 指示文件是否打开。
open 打开文件。
overflow 将新字符插入到已满缓冲区时可以调用的受保护虚函数。
pbackfail 受保护虚拟成员函数尝试将元素放回到输入流中,随后使它成为当前元素(由下一个指针指向)。
seekoff 受保护虚拟成员函数尝试更改受控制流的当前位置。
seekpos 受保护虚拟成员函数尝试更改受控制流的当前位置。
setbuf 受保护虚拟成员函数执行特定于每个派生流缓冲区的操作。
Swap 为提供的 basic_filebuf 参数的内容交换此 basic_filebuf 的内容。
sync 受保护虚函数尝试将受控制流与任何关联的外部流同步。
uflow 受保护虚函数从输入流中提取当前元素。
underflow 受保护虚函数从输入流中提取当前元素。

要求

标头:<fstream>

命名空间: std

basic_filebuf::basic_filebuf

构造 basic_filebuf 类型的对象。

basic_filebuf();

basic_filebuf(basic_filebuf&& right);

备注

第一个构造函数将 null 指针存储在控制输入缓冲区和输出缓冲区的所有指针中。 同时它还将 null 指针存储在文件指针中。

第二个构造函数初始化具有 right 的内容的对象,将其视为右值引用。

basic_filebuf::char_type

将类型名与 Char_T 模板参数关联。

typedef Char_T char_type;

basic_filebuf::close

关闭文件。

basic_filebuf<Char_T, Tr> *close();

返回值

如果文件指针为 null 指针,则该成员函数返回 null 指针。

备注

close 调用 fclose(fp)。 如果该函数返回一个非零值,则该函数返回 null 指针。 否则,它将返回 this,指示已成功关闭文件。

对于宽流,如果自打开流后,或者自上次调用 streampos 后发生任何插入,该函数都将调用 overflow。 它还将根据需要通过使用文件转换 facet fac 调用 fac.unshift,插入任何所需的序列,以还原初始转换状态。 每个生成的 char 类型的元素 byte 都被写入由文件指针 fp 指定的关联流,就像连续调用窗体 fputc(byte, fp) 一样。 如果调用 fac.unshift 或任何写入失败,该函数将不会成功。

示例

下面的示例假设当前目录中有两个文件:basic_filebuf_close.txt(内容为“testing”)和 iotest.txt(内容为“ssss”)。

// basic_filebuf_close.cpp
// compile with: /EHsc
#include <fstream>
#include <iostream>

int main() {
   using namespace std;
   ifstream file;
   basic_ifstream <wchar_t> wfile;
   char c;
   // Open and close with a basic_filebuf
   file.rdbuf()->open( "basic_filebuf_close.txt", ios::in );
   file >> c;
   cout << c << endl;
   file.rdbuf( )->close( );

   // Open/close directly
   file.open( "iotest.txt" );
   file >> c;
   cout << c << endl;
   file.close( );

   // open a file with a wide character name
   wfile.open( L"iotest.txt" );

   // Open and close a nonexistent with a basic_filebuf
   file.rdbuf()->open( "ziotest.txt", ios::in );
   cout << file.fail() << endl;
   file.rdbuf( )->close( );

   // Open/close directly
   file.open( "ziotest.txt" );
   cout << file.fail() << endl;
   file.close( );
}
t
s
0
1

basic_filebuf::int_type

使 basic_filebuf 范围中的此类型等效于 Tr 范围中具有相同名称的类型。

typedef typename traits_type::int_type int_type;

basic_filebuf::is_open

指示文件是否打开。

bool is_open() const;

返回值

如果文件指针不为空,则为 true

示例

// basic_filebuf_is_open.cpp
// compile with: /EHsc
#include <fstream>
#include <iostream>

int main( )
{
   using namespace std;
   ifstream file;
   cout << boolalpha << file.rdbuf( )->is_open( ) << endl;

   file.open( "basic_filebuf_is_open.cpp" );
   cout << file.rdbuf( )->is_open( ) << endl;
}
false
true

basic_filebuf::off_type

使 basic_filebuf 范围中的此类型等效于 Tr 范围中具有相同名称的类型。

typedef typename traits_type::off_type off_type;

basic_filebuf::open

打开文件。

basic_filebuf<Char_T, Tr> *open(
    const char* filename,
    ios_base::openmode mode,
    int protection = (int)ios_base::_Openprot);

basic_filebuf<Char_T, Tr> *open(
    const char* filename,
    ios_base::openmode mode);

basic_filebuf<Char_T, Tr> *open(
    const wchar_t* filename,
    ios_base::openmode mode,
    int protection = (int)ios_base::_Openprot);

basic_filebuf<Char_T, Tr> *open(
    const wchar_t* filename,
    ios_base::openmode mode);

参数

filename
要打开的文件的名称。

mode
ios_base::openmode 中的枚举之一。

protection
默认文件打开保护,等同于 _fsopen, _wfsopen 中的 shflag 参数

返回值

如果缓冲区已打开,或者文件指针为空指针,则该函数返回一个空指针。 否则,它将返回 this

注解

此函数使用 FILE * 支持 basic_filebuf,就像调用了 fopen/wfopen(filename, strmode) 一样。 strmodemode & ~()ate | binary

  • ios_base::in 变为 "r"(打开现有文件进行读取)。
  • ios_base::outios_base::out | ios_base::trunc 变为 "w"(截断现有文件或者创建以进行写入)。
  • ios_base::out | app 变为 "a"(打开现有文件以追加所有写入)。
  • ios_base::in | ios_base::out 变为 "r+"(打开现有文件以读取和写入)。
  • ios_base::in | ios_base::out | ios_base::trunc 变为 "w+"(截断现有文件或者创建以读取和写入)。
  • ios_base::in | ios_base::out | ios_base::app 变为 "a+"(打开现有文件以读取和追加所有写入)。

如果 mode & ios_base::binary 为非零,该函数将 b 追加到 strmode,以打开一个二进制流而不是文本流。 如果 mode & ios_base::ate 为非零,并且文件已成功打开,则流中的当前位置位于文件末尾。 如果失败,文件将关闭。

如果上述操作已成功完成,则确定文件转换 facet:use_facet<codecvt<Char_T, char, traits_type::state_type> >(getloc),供 underflowoverflow 使用。

如果无法成功打开文件,则返回 nullptr

示例

有关使用 open 的示例,请参阅 basic_filebuf::close

basic_filebuf::operator=

分配此流缓冲区对象的内容。 这是一种移动赋值,所涉 rvalue 不会留下副本。

basic_filebuf& operator=(basic_filebuf&& right);

参数

right
basic_filebuf 对象的右值引用。

返回值

返回 *this

备注

成员运算符使用 right 内容替换该对象的内容,被视为右值引用。 有关详细信息,请参阅 Rvalue 引用声明符:&&

basic_filebuf::overflow

当新字符插入到已满缓冲区时调用。

virtual int_type overflow(int_type _Meta = traits_type::eof);

参数

_Meta
要插入到缓冲区的字符或 traits_type::eof

返回值

如果该函数不成功,它将返回 traits_type::eof。 否则,它将返回 traits_type::not_eof(_Meta)

备注

如果 _Meta != traits_type::eof,受保护的虚拟成员函数会尝试将元素 ch = traits_type::to_char_type(_Meta) 插入到输出缓冲区。 它可以用多种方法执行此操作:

  • 如果写入位置可用,它可将元素存储到写入位置并增加输出缓冲区的下一个指针。

  • 它可以通过为输出缓冲区分配新的或额外的存储空间,提供写入位置。

  • 它可以根据需要使用文件转换 facet fac 调用 fac.out,转换输出缓冲区中的任何挂起输出,后面是 ch。 每个生成的 char 类型的元素 ch 都被写入由文件指针 fp 指定的关联流,就像连续调用窗体 fputc(ch, fp) 一样。 如果任何转换或写入失败,该函数不会成功。

basic_filebuf::pbackfail

尝试将元素放回到输入流中,随后使它成为当前元素(由下一个指针指向)。

virtual int_type pbackfail(int_type _Meta = traits_type::eof);

参数

_Meta
要插入到缓冲区的字符或 traits_type::eof

返回值

如果该函数不成功,它将返回 traits_type::eof。 否则,它将返回 traits_type::not_eof(_Meta)

注解

受保护虚拟成员函数将元素放回到输入缓冲区中,随后使它成为当前元素(由下一个指针指向)。 如果 _Meta == traits_type::eof,要推送回的元素在当前元素之前实际上已是流中的一个元素了。 否则,该元素被替换为 ch = traits_type::to_char_type(_Meta)。 该函数可以用多种方法放回元素:

  • 如果 putback 位置可用,且存储在该位置的元素等于 ch,则它可以递减输入缓冲区中的下一个指针。

  • 如果该函数可以使 putback 位置可用,则它可以这样做,将下一个指针指向该位置,并将 ch 存储在该位置。

  • 如果该函数可以将一个元素放回输入流,它可以这样做,例如通过调用类型为 char 的元素的 ungetc

basic_filebuf::pos_type

使 basic_filebuf 范围中的此类型等效于 Tr 范围中具有相同名称的类型。

typedef typename traits_type::pos_type pos_type;

basic_filebuf::seekoff

尝试更改受控制流的当前位置。

virtual pos_type seekoff(
    off_type _Off,
    ios_base::seekdir _Way,
    ios_base::openmode _Which = ios_base::in | ios_base::out);

参数

_Off
要搜寻的相对于 _Way 的位置。

_Way
偏移操作的起点。 请参阅 seekdir,查看可能的值。

_Which
指定指针位置的模式。 默认允许修改读取和写入位置。

返回值

返回新位置或无效的流位置。

注解

受保护的虚拟成员函数尝试更改受控制流的当前位置。 对于类 basic_filebuf<Char_T, Tr> 的对象,流位置可以通过类型为 fpos_t 的对象表示,它存储偏移量以及分析宽流所需的任何状态信息。 偏移量零是指流的第一个元素。 (类型为 pos_type 的对象存储至少一个 fpos_t 对象。)

对于打开供读取和写入的文件,输入流和输出流串联放置。 若要在插入和提取之间切换,必须调用 pubseekoffpubseekpos。 调用 pubseekoff(因而调用 seekoff)对于文本流二进制流宽流有各种限制。

如果文件指针 fp 为空指针,函数将失败。 否则,它尝试通过调用 fseek(fp, _Off, _Way) 更改流位置。 如果该函数成功,并且最终位置 fposn 可通过调用 fgetpos(fp, &fposn) 来确定,则该函数将成功。 如果函数成功,则返回类型为 pos_type 的值,其中包含 fposn。 否则,返回一个无效的流位置。

basic_filebuf::seekpos

尝试更改受控制流的当前位置。

virtual pos_type seekpos(
    pos_type _Sp,
    ios_base::openmode _Which = ios_base::in | ios_base::out);

参数

_Sp
要搜寻的位置。

_Which
指定指针位置的模式。 默认允许修改读取和写入位置。

返回值

如果文件指针 fp 为空指针,函数将失败。 否则,它尝试通过调用 fsetpos(fp, &fposn) 更改流位置,其中 fposn 是存储在 pos 中的 fpos_t 对象。 如果该函数成功,则该函数将返回 pos。 否则,返回一个无效的流位置。 若要确定流位置是否有效,请比较返回值和 pos_type(off_type(-1))

备注

受保护的虚拟成员函数尝试更改受控制流的当前位置。 对于类 basic_filebuf<Char_T, Tr> 的对象,流位置可以通过类型为 fpos_t 的对象表示,它存储偏移量以及分析宽流所需的任何状态信息。 偏移量零是指流的第一个元素。 (类型为 pos_type 的对象存储至少一个 fpos_t 对象。)

对于打开供读取和写入的文件,输入流和输出流串联放置。 若要在插入和提取之间切换,必须调用 pubseekoffpubseekpos。 调用 pubseekoff(并调用 seekoff)对于文本流、二进制流和宽流有各种限制。

对于宽流,如果自打开流后,或者自上次调用 streampos 后发生任何插入,该函数都将调用 overflow。 它还将根据需要通过使用文件转换 facet fac 调用 fac.unshift,插入任何所需的序列,以还原初始转换状态。 每个生成的 char 类型的元素 byte 都被写入由文件指针 fp 指定的关联流,就像连续调用窗体 fputc(byte, fp) 一样。 如果调用 fac.unshift 或任何写入失败,该函数将不会成功。

basic_filebuf::setbuf

执行特定于每个派生流缓冲区的操作。

virtual basic_streambuf<Char_T, Tr> *setbuf(
    char_type* _Buffer,
    streamsize count);

参数

_Buffer
指向缓冲区的指针。

count
缓冲区的大小。

返回值

如果文件指针 fp 为 null 指针,则受保护成员函数将返回零。

备注

setbuf 调用 setvbuf( fp, (char*) _Buffer, _IOFBF, count * sizeof( Char_T)) 以提供从 _Buffer 开始的 count 个元素组成的数组作为流的缓冲区。 如果该函数返回一个非零值,则该函数返回 null 指针。 否则,它将返回 this 表示成功。

basic_filebuf::swap

将此 basic_filebuf 的内容与提供的 basic_filebuf 的内容进行交换。

void swap(basic_filebuf& right);

参数

right
对另一个 basic_filebuf 的 lvalue 引用。

basic_filebuf::sync

尝试将受控制流与任何关联的外部流同步。

virtual int sync();

返回值

如果文件指针 fp 为空指针,则返回零。 否则,仅当调用 overflowfflush(fp) 成功刷新流的任何挂起输出时,才返回零。

basic_filebuf::traits_type

将类型名与 Tr 模板参数关联。

typedef Tr traits_type;

basic_filebuf::underflow

从输入流中提取当前元素。

virtual int_type underflow();

返回值

如果该函数不成功,它将返回 traits_type::eof。 否则,它将返回 ch,如“注解”部分中所述进行转换。

备注

受保护的虚拟成员函数尝试从输入流提取当前元素 ch,并返回元素作为 traits_type::to_int_type(ch)。 它可以用多种方法执行此操作:

  • 如果读取位置可用,它采用 ch 作为存储在读取位置中的元素,并提升输入缓冲区的下一个指针。

  • 它可以读取类型为 char 的一个或多个元素,就像连续调用窗体 fgetc(fp) 一样,并根据需要通过使用文件转换 facet fac 调用 fac.in,将它们转换为类型为 Char_T 的元素 ch。 如果任何读取或转换失败,该函数不会成功。

另请参阅

<fstream>
C++ 标准库中的线程安全
iostream 编程
iostreams 约定