zoukankan      html  css  js  c++  java
  • 【C++ IO机制】stream_buf 解析

    stream_buf 解析

    1. stream_buf原型:

    template <class CharT, class Traits = std::char_traits<CharT>>
    class basic_streambuf;

    【注意】

    typedef basic_streambuf<char> streambuf;

    用于输出的 streambuf

    streambuf 使用三个指针来管理相应的输出缓冲区(缓冲区需要自行设置),分别由接口 pbasepptr和 epptr 返回。其中 pbase 是缓冲区的基指针,指向缓冲区的第一个字节,epptr 是缓冲区的尾指针,指向其最后一个字节的下一个字节(类似于 iter.end() 的作用),而 pptr 指向缓冲区当前可用的位置,也就是pptr 之前都已经被数据所填充,如下图:

     streambuf 定义的输出相关的函数主要有 sputc 和 sputn,前者输出一个字符到缓冲区,并且将指针 pptr 向后移动一个字符,后者调用函数 xsputn 连续输出多个字符,xsputn 默认的实现就是多次调用 sputc。由于缓冲区有限,当 pptr 指针向后移动满足 pptr() == epptr 时,说明缓冲区满了,这时将会调用函数 overflow 将数据写入到外部设备并清空缓冲区;清空缓冲区的方式则是调用 pbump 函数将指针 pptr 重置。我们可以通过如下的类来实现自定义的输出 buffer:

    用于输入的 streambuf

    同管理输出缓冲区一样,streambuf 也使用三个指针,eback()gptr() 以及 egptr() 分别指示输入缓冲区的开始字节,当前可用字节以及缓冲区尾的下一字节,如下图所示:

    streambuf 类同样定义了如下几个函数来支持对于输入缓冲区的读取和管理:

    • sgetc: 从输入缓冲区中读取一个字符;
    • sbumpc: 从输入缓冲区中读取一个字符,并将 gptr() 指针向后移动一个位置;
    • sgetn: 从输入缓冲区中读取 n 个字符;
    • sungetc: 将缓冲区的 gptr() 指针向前移动一个位置;
    • sputbackc: 将一个读取到的字符重新放回到输入缓冲区中;

    与输出缓冲区不同的是,输入缓冲区需要额外提供 putback 操作,也就是将字符放回到输入缓冲区内。

     

    1. 示例
     1 #include <iostream>
     2 #include <fstream>
     3 
     4 int main()
     5 {
     6   std::ifstream ifs("test.txt");
     7   if (ifs.good())
     8   {
     9     std::streambuf *pbuf = ifs.rdbuf();
    10     char c;
    11     ifs >> c;
    12     std::streamsize size = pbuf->in_avail();
    13     std::cout << "first character in file: " << c << '\n';
    14     std::cout << size << " characters in buffer after it\n";
    15   }
    16   ifs.close();
    17 
    18   return 0;
    19 }

    说明: test.file 文件内容如下:

    this is test file!

    输出:

    first character in file: t
    18 characters in buffer after it
     1 #include <iostream>
     2 #include <sstream>
     3 
     4 int main()
     5 {
     6   std::stringstream stream("Hello, world");
     7   std::cout << "sgetc() returned '" << (char)stream.rdbuf()->sgetc() << "'\n";
     8   std::cout << "peek() returned '" << (char)stream.peek() << "'\n";
     9   std::cout << "get() returned '" << (char)stream.get() << "'\n";
    10 }

    输出:

    sgetc() returned 'H'
    peek() returned 'H'
    get() returned 'H'
    

    说明:

    sgetc() 返回当前位置的字符。
    sbumpc() 返回当前位置的字符,并将当前位置前进到下一个字符。
    snextc() 将当前位置前进到下一个字符并返回下一个字符。

    参考资料

    1. std::streambuf从示例到应用

    2. stream_buff 解析【cppreference.com】

    3. C/C++编程:流缓冲类std::basic_streambuf

  • 相关阅读:
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    基于分布式锁解决定时任务重复问题
    基于Redis的Setnx实现分布式锁
    基于数据库悲观锁的分布式锁
    使用锁解决电商中的超卖
  • 原文地址:https://www.cnblogs.com/sunbines/p/15730390.html
Copyright © 2011-2022 走看看