我该如何查找从std :: istream中可用的字节数?

9
如果我想要将 std::istream 的内容读取到缓冲区中,我需要先找出有多少数据可用来确定缓冲区的大小。为了从 istream 中获取可用字节数,我目前正在执行以下操作:
std::streamsize available( std::istream &is )
{
    std::streampos pos = is.tellg();
    is.seekg( 0, std::ios::end );
    std::streamsize len = is.tellg() - pos;
    is.seekg( pos );
    return len;
}

同样地,由于我认为std::istream::eof()不是一个非常有用的函数,所以为了找出istream的获取指针是否在流的末尾,我正在这样做:

bool at_eof( std::istream &is )
{
    return available( is ) == 0;
}

我的问题:

有没有更好的方法从istream中获取可用字节数?如果标准库中没有,那么在boost库中呢?


5
我需要先查找有多少数据可用,才能确定缓冲区应该设置多大 - 这并不准确。请参考我在stackoverflow上的回答(第二部分)。 - Björn Pollex
哇,有趣的答案。我认为这会起作用。谢谢! - edam
@edam:为什么你需要提前知道缓冲区大小,难道你不能读取与你拥有的缓冲区一样多的数据吗? - Alok Save
如果你需要一次性读取所有数据,那么@Space_C0wb0y在链接中所提供的答案正好能够做到这一点,否则你可以根据你所分配的大小逐步读取数据并进一步使用它。无论如何,所建议的解决方案似乎更好。 - Alok Save
1
你可能想看一下我对之前问题的回答。总的来说,虽然@Space_C0wb0y的回答看起来很好,但是有其他更好的选择,几乎不管你更偏向速度还是优雅(特别是sstream << stream.rdbuf();这种优雅而且相当快的方式,尽管不是最快的)。 - Jerry Coffin
显示剩余2条评论
2个回答

4
对于std::cin,您无需担心缓冲,因为它已经被缓冲了,并且您无法预测用户键入了多少个键。
对于打开的二进制std::ifstream,它们也具有缓冲功能,您可以调用seekg(0, std::ios:end)tellg()方法来确定有多少字节。
在读取后,您还可以调用gcount()方法。
char buffer[SIZE];

while (in.read(buffer,SIZE))
{
  std::streamsize num = in.gcount();
  // call your API with num bytes in buffer 
}

通过使用 std::getline(inputstream, a_string) 读取文本输入,并在之后分析该字符串可能会很有用。


3

根据问题的描述,你需要一个答案,这里提供给你。

为了知道要设置多大的缓冲区,我必须先查找可用的数据量 - 这是不正确的。请参见我之前回答的这个问题(第二部分)。


这似乎不太对劲...使用istream_iterator< char >在使用copy()时会跳过istream上的空格。因此,你最终得到的vector< char>缓冲区中所有的空格都被删除了! - edam

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接