c++11 标准模板(STL)(std::basic_filebuf)(七)

定义于头文件 <fstream>

template<

    class CharT,
    class Traits = std::char_traits<CharT>

> class basic_filebuf : public std::basic_streambuf<CharT, Traits>

std::basic_filebuf 是关联字符序列为文件的 std::basic_streambuf 。输入序列和输出序列都关联到同一文件,并为两种操作维护连接文件位置。

函数 underflow() 和 overflow()/sync() 进行文件和缓冲区的获取放置区之间的实际 I/O 。 CharT 不是 char 时,多数实现在文件存储多字节字符,并用 std::codecvt 平面进行宽/多字节字符转换。

亦为常用字符类型定义二个特化:

类型定义
filebufbasic_filebuf<char>
wfilebufbasic_filebuf<wchar_t>

受保护成员函数

提供用户供应的缓冲区,或将此 filebuf 转变为无缓冲

std::basic_filebuf<CharT,Traits>::setbuf

protected:
virtual std::basic_streambuf<CharT, Traits>* setbuf( char_type* s, std::streamsize n )

s 为空指针且 n 为零,则 filebuf 变为对输出无缓冲,这表示 pbase()pptr() 为空,而任何输出都被立即发送到文件。

否则,如同调用 setbuf() ,以用户提供的首元素为s 所指向的字符数组替换内部缓冲区(受控制字符序列),并允许此 std::basic_filebuf 将该数组中的至多 n 个字节用于缓冲。

此函数为受保护虚,它仅可通过 pubsetbuf() 或从导出自 std::basic_filebuf 的用户定义类调用。

参数

s-指向用户提供缓冲区的首个 CharT 的指针或空指针
n-用户提供缓冲区中的 CharT 元素数或零

返回值

this 。

注意

可以使用此函数时的条件,和使用提供的缓冲区的方式是实现定义的。

  • GCC 4.6 libstdc++

setbuf() 仅可在 std::basic_filebuf 未与文件关联时调用(否则无效果)。拥有用户提供的缓冲区时,每次从文件读取 n-1 字节。

  • Clang++3.0 libc++

setbuf() 可在打开文件后,但要在任何 I/O 前调用(否则可能崩溃)。拥有用户提供缓冲区时,从文件读取适合缓冲区的 4096 最大倍数字节。

  • Visual Studio 2010

setbuf() 可在任何时候调用,即使在某个 I/O 发生后。缓冲区的当前内容若存在则丢失。

标准不定义此函数的任何行为,除了要求在任何 I/O 发生前调用的 setbuf(0, 0) 设置输出为无缓冲。

调用示例

#include <fstream>
#include <iostream>
#include <string>

int main()
{
    int cnt = 0;
    std::ifstream file;
    char buf[10241];

    file.rdbuf()->pubsetbuf(buf, sizeof buf);
    file.open("test.txt");

    if (!file.is_open())
    {
        std::cout << "open error" << std::endl;
    }

    for (std::string line; getline(file, line);)
    {
        ++cnt;
    }
    std::cout << cnt << std::endl;
    return 0;
}

 

用相对寻址重寻位文件位置

std::basic_filebuf<CharT,Traits>::seekoff
protected:

virtual pos_type seekoff( off_type off,
                          std::ios_base::seekdir dir,

                          std::ios_base::openmode which = std::ios_base::in | std::ios_base::out );

若可能,则重寻位文件指针到距文件起始、结尾或当前位置准确 off 个字符的位置(取决于 dir 的值)。

若关联文件未打开( is_open()==false ),则立即失败。

若多字节字符编码依赖状态( codecvt::encoding() 返回 -1 )或为变长( codecvt::encoding() 返回 ​0​ ),而偏移 off 非 ​0​ ,则立即失败:此函数无法确定对应 off 个字符的字节数。

dir 不是 std::basic_ios::cur 或偏移 off 非 ​0​ ,且此 filebuf 对象上最近做的操作是输出(即放置缓冲区非空,或最近调用的函数是 overflow() ),则调用 std::codecvt::unshift 确定需要的反迁移序列,并通过调用 overflow() 写入该序列到文件。

然后转换参数 dir 为 int 类型值 whence 如下:

dir 的值whence 的值
std::basic_ios::begSEEK_SET
std::basic_ios::endSEEK_END
std::basic_ios::curSEEK_CUR

然后,若字符编码为定宽( codecvt::encoding() 返回某个正值 width ),则如同用 std::fseek(file, width*off, whence) 移动文件指针。

否则,如同用 std::fseek(file, 0, whence) 移动文件指针。

基类函数签名所要求的 openmode 参数通常被忽略,因为 std::basic_filebuf 只维护一个文件位置。

参数

off-要设置位置指示器到的相对位置。
dir-定义要应用相对偏移到的基位置。它能为下列常量之一:
常量解释
beg流的开始
end流的结尾
cur流位置指示器的当前位置
which-定义要影响输入和/或输出序列的哪一个。它能为下列常量之一或其组合:
常量解释
in影响输入序列
out影响输出序列

返回值

新构造的 pos_type 类型对象,存储结果文件位置,或在失败时为 pos_type(off_type(-1)) 。

注意

seekoff() 为 std::basic_streambuf::pubseekoff 所调用,它又为 std::basic_istream::seekg 、 std::basic_ostream::seekp 、 std::basic_istream::tellg 和 std::basic_ostream::tellp 所调用。

调用示例

#include <iostream>
#include <fstream>
#include <locale>
int main()
{
    // 准备 10 字节文件,保有 4 个 UTF8 中的字符
    std::ofstream("text.txt") << u8"z\u00df\u6c34\U0001d10b";
    // 用非转换编码打开
    std::ifstream f1("text.txt");
    std::cout << "f1's locale's encoding() returns "
              << std::use_facet<std::codecvt<char, char, std::mbstate_t>>(f1.getloc()).encoding()
              << std::endl
              << "pubseekoff(3, beg) returns "
              << f1.rdbuf()->pubseekoff(3, std::ios_base::beg) << std::endl
              << "pubseekoff(0, end) returns "
              << f1.rdbuf()->pubseekoff(0, std::ios_base::end) << std::endl;

    // 用 UTF-8 打开
    std::wifstream f2("text.txt");
    f2.imbue(std::locale("C"));
    std::cout << "f2's locale's encoding() returns "
              << std::use_facet<std::codecvt<wchar_t, char, std::mbstate_t>>(f2.getloc()).encoding()
              << std::endl
              << "pubseekoff(3, beg) returns "
              << f2.rdbuf()->pubseekoff(3, std::ios_base::beg) << std::endl
              << "pubseekoff(0, end) returns "
              << f2.rdbuf()->pubseekoff(0, std::ios_base::end) << std::endl;
}
输出

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值