C++ IO 体系
ios_base定义了同字符类型无关的属性和操作,istream和ostream分别定义了同输入和输出相关的操作,iostream同时支持输入和输出。它们负责字符串的可视化操作。如 >> << 流式操作重载。
由图可以看出,在stream 的实现中,除了虚基类IOS_BASE之外,所有的类内部都有一个streambuf,提供了缓冲功能和真正的操作外部设备的方法。streambuf 是一个虚基类不能被实例化,现有的标准库中,streambuf有两个子类,分别是stringbuf 和 filebuf,这两个子类可以被实例化。我们常用的文件流和字符串流,内部的缓冲区就是这两个类。如果需要订制自己的流处理方式,就可以从streambuf派生出自己的类。
streambuf 保护函数实现了缓冲区的管理,输入和输出功能。内部有三个get指针(gfirst,gnext,glast),三个put指针(pfirst,pnext,plast)。分别可以使用 eback(),gptr(),egptr()和pbase(),pptr(),epptr()获得。
缓冲区管理:
- setbuf:设置缓冲区
- seekoff:根据相对位置移动内部指针
- seekpos:根据绝对位置移动内部指针
- sync:同步缓冲区数据(flush)
- showmanyc:得到流中可获取的字符数
输入功能
- underflow(c):当缓冲区不可用时调用,用于获取流中当前的字符。不移动gnext,默认返回EOF
- uflow():默认返回underflow,同时后移gnext。如果没有提供缓冲区,必须重写underflow和uflow
- xsgetn(s,n):从流中读取n个字符到缓冲区中,并返回读取的字符数,默认多次调用sbumpc,可以重写以改善读取多个字符的性能。若当前缓冲区不可用,则调用一次uflow。
- pbackfail:回写失败时调用
- sgetc,sbumpc 读取一个字符,后者会将读取位置后移一个位置。如果没有提供缓冲区或缓冲区已满,sgetc会调用underflow,sbumpc会调用uflow,从外部设备读取更多数据。
- sgetn:读取多个字符,会调用xsgen。
输出功能
- overflow(c):当put缓冲区不可用时调用,将数据写入外部设备并清空缓冲区。当c==EOF时,流写入结束。对应输入函数uflow
- xsputn(s,n):将缓冲区s的n个字符写入外部设备,并返回写入的字符数,默认对每个字符调用sputc,因此可以重写以优化多个字符输出。对应输入函数xsgetn。
- sputc(输出一个字符),sputn(输出多个字符):如果提供了缓冲区,将复制到缓冲区,如果缓冲区已满或没有提供缓冲区,调用overflow。sputn会调用xsputn。