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
对象控制与打开的文件关联的流。 另外,它还存储指向两个文件转换方面的指针,以供受保护的成员函数 overflow 和 underflow 使用。 有关详细信息,请参阅 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)
一样。 strmode
从 mode & ~(
)
ate
|
binary
:
ios_base::in
变为"r"
(打开现有文件进行读取)。- ios_base::out 或
ios_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
)
,供 underflow 和 overflow 使用。
如果无法成功打开文件,则返回 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
对象。)
对于打开供读取和写入的文件,输入流和输出流串联放置。 若要在插入和提取之间切换,必须调用 pubseekoff
或 pubseekpos
。 调用 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
对象。)
对于打开供读取和写入的文件,输入流和输出流串联放置。 若要在插入和提取之间切换,必须调用 pubseekoff
或 pubseekpos
。 调用 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
为空指针,则返回零。 否则,仅当调用 overflow 和 fflush(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)
一样,并根据需要通过使用文件转换 facetfac
调用fac.in
,将它们转换为类型为Char_T
的元素ch
。 如果任何读取或转换失败,该函数不会成功。