5

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

我正在与我的一位同事讨论我试图编写的另一个流类的实现,我说我可能会遵循这个设计;但他说,与其让用户每次都调用gcount,不如像这样读取原型istream& read (char* s, streamsize n, size_t &bytes_read),这样它就可以在一次调用中结束,而前者更笨拙。我无法为std的设计选择辩护。背后的真正原因是istream::read什么?

4

4 回答 4

4

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

使用单独的方法,您可以将可能需要或可能不需要的不同信息的接口解耦。

于 2010-10-07T15:41:34.003 回答
3

请尝试使用 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 );
于 2010-10-11T12:29:37.680 回答
0

std::istream有原型 应该通过调用得到实际读取的字节数 istream& read (char* s, streamsize n)可以从中知道 istream::gcount()其有效性。istreamios::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可能与 a 的大小不同double,因此我们无法使用它来指定数组istream::gcount()中第一个元素的大小。data

于 2010-10-10T14:40:08.823 回答
0

针对最初的问题,错误检查调用在 C 语言年轻时是一种流行的编程风格,但很快就过时了。发生的事情是一些不是很错误的小事,但几乎总是存在一段时间,直到它们被社区称为坏事并被标记为坏事。不幸的是,这段代码是在这种小小的反模式被广泛讨论之前编写的。

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

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

不过,我同意 readsome 是阅读的不错选择。

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

于 2011-05-20T01:48:07.467 回答