其他语言

本类阅读TOP10

·基于Solaris 开发环境的整体构思
·使用AutoMake轻松生成Makefile
·BCB数据库图像保存技术
·GNU中的Makefile
·射频芯片nRF401天线设计的分析
·iframe 的自适应高度
·BCB之Socket通信
·软件企业如何实施CMM
·入门系列--OpenGL最简单的入门
·WIN95中日志钩子(JournalRecord Hook)的使用

分类导航
VC语言Delphi
VB语言ASP
PerlJava
Script数据库
其他语言游戏开发
文件格式网站制作
软件工程.NET开发
由一个Bug看ifstream中read()与readsome()的区别

作者:未知 来源:月光软件站 加入时间:2005-2-28 月光软件站

 

ifstream中read()与readsome()的区别。

项目中出现一个很有趣的Bug,程序读入一个特定的二进制文件中的数据,进行一些处理,可是每当这个文件的数据量超过某个特定值(这个值不大,400K左右)的时候运行结果就出错。

追查Bug是程序员的一项基本功,也是最能体现实力的地方之一。这个Bug最终在3天追捕之后被一个同事抓获。原因确是因为我写的读取文件的模块中使用了fsream::readsome()函数。改成fsream::read()就可以了。

惊悸之余,特地比较详细的看了关于流的解释。

首先,fstream是basic_fstream模板类关于char的一个实例。

typedef basic_fstream<char, char_traits<char> > fstream;

basic_fstream的由basic_iostream派生的

template <class Elem, class Tr = char_traits<Elem> >
    class basic_fstream : public basic_iostream<Elem, Tr>

basic_iostream是由basic_istream和basic_ostream派生的。

template <class Elem, class Tr = char_traits<Elem> >
   class basic_iostream : public basic_istream<Elem, Tr>,
      public basic_ostream<Elem, Tr> 

我们使用的fstream::readsome实际上是 basic_istream::readsome().

而basic_istream是从basic_ios派生的

template <class Elem, class Tr = char_traits<Elem> >
   class basic_istream
      : virtual public basic_ios<Elem, Tr>

basic_ios是从ios_base派生的

template <class Elem, class Traits>
   class basic_ios : public ios_base
派生关系图如下:

 

在流的实现上,采取了缓冲区I/O的方式,每个stream对象中都有一个对于一个streambuf,对于流的操作缺省状态下是对于缓冲区的操作,直到出现迫使他和缓冲区同步的操作。

而read()和readsome()的区别就在于此,readsome()并不迫使同步缓冲区,而read()读取的时候,如果发现缓冲区中的数据不够,就试图从关联的数据源(这里就是文件)来读取。

readsome()函数之后调用gcount()可以检测究竟有多少字节被操作了。good()函数也可以检测,而我没有做。

 

我当初选择readsome()是以为read()是操作charactor的,而readsome()才是操作二进制的。

 

 




相关文章

相关软件