理解std :: istream :: read的设计

时间:2010-10-07 14:18:19

标签: c++ iostream istream c++-standard-library

std::istream原型istream& read (char* s, streamsize n)应该通过调用istream::gcount()获取实际读取的字节数,istream的有效性可以从ios::good知道。

我正在和我的一位同事讨论另一个流类的实现,我在那里说我可能会遵循这个设计;但是他说,不是让用户每次都打电话给 gcount ,而是可以像这样istream& read (char* s, streamsize n, size_t &bytes_read)阅读原型,这样它就可以在一次通话中结束而前者是笨拙的。我无法捍卫std的设计选择。 istream::read背后的真正原理是什么?

4 个答案:

答案 0 :(得分:4)

我认为这是因为C ++通常不强制每个人都不需要的接口。如果您需要read接受某些人不关心的参数,那么它会导致额外的编码工作(声明一个额外的int作为参数传递)。无论客户端是否关心,它也始终保存读取的字节数(某些客户端可能只关心读取失败,如eof / fail位所示)。

使用单独的方法,您可以为界面分配可能需要或可能不需要的不同信息。

答案 1 :(得分:2)

尝试使用readsome命令,

streamsize readsome ( char* buf, streamsize num );

buf是你的缓冲区,num是你想要读取的字节数,当然最多是缓冲区中可用的字节数。

返回值是实际读取的字节数。

要将文件读到最后,您可以循环:

char buf[BUF_SIZE]
streamsize bytesRead;
do
{
   bytesRead = instr.readsome( buf, BUF_SIZE );
   // do stuff with the bytes you read, if any
} while ( bytesRead == BUF_SIZE );

答案 2 :(得分:0)

  

std::istream有原型   istream& read (char* s, streamsize n)   实际读取的字节数   应该通过电话来获得   istream::gcount(),也是有效性   可以从istream知道   ios::good

istream::read(char* s, streamsize n)NULL的数组中读取大小为n的无格式数据块(没有s终止)。尽管s是指向char的指针,但您可以使用istream::read来读取二进制数据。例如,您可以拥有一个istream来保存双精度数组的值(假设字节顺序是正确的):

unsigned int count;
input.read(reinterpret_cast<char*>(&count), sizeof(count));
double* data = new double[count];

for (unsigned int i = 0; i < count; ++i)
    input.read(reinterpret_cast<char*>(data[i]), sizeof(double));

istream::gcount()返回上一次istream::read调用中读取的字节数。在这种情况下,我们发现count的大小可能与double的大小不同,因此我们无法使用istream::gcount()来指定第一个元素的大小在data数组中。

答案 3 :(得分:0)

在回答最初的问题时,当C年轻时,有错误检查电话是一种流行的编程风格,但很快就失去了时尚。会发生什么事情并不是非常错误,但是在他们被社区召唤并被标记为糟糕的情况之前,他们几乎总是存在一段时间。这段代码不幸之前已经被广泛讨论过的小反模式。

为了回应Cash Cow的解决方案,我认为存在一个错误。如果您正在等待IO并且有足够的字符来部分填充缓冲区,则该函数将返回并且while循环将在文件完全读取之前结束。因此,如果直接写入原始IO,他的解决方案可能会正确运行,但无法在缓冲IO上运行。

当然,正确的解决方案是在设置EOF标志时结束while循环。目前我不确定什么是badbit设置时的最佳响应,但你也应该处理这种情况。

我同意readome是一个不错的替代阅读。

编辑: 有时readome不可用(一些VC ++版本)。在这种情况下,读取不可用。