【问题标题】:Get Stream Size Without Changing Stream Position在不更改流位置的情况下获取流大小
【发布时间】:2015-10-19 18:05:20
【问题描述】:

我熟悉的获取流大小的方法包括:

foo.seekg(0, ios::end);
int bar = tellg();
foo.seekg(0, ios::beg);

但我宁愿不移动流的位置!它显然已经知道它的缓冲区的起点和终点,那为什么我不能直接访问该信息呢?

在我记忆深处的某个地方,我认为有一种方法可以从流的iosios_base 中获取此信息。但我就是想不起来。其他人能记得如何做到这一点吗?

【问题讨论】:

  • 是什么让您认为它知道底层数据的真正起点/终点? foo 到底是什么类型的流?如果它是一个文件流,您是否希望它一次将整个文件缓冲在内存中?根据流类型,需要查找。
  • '流大小'已经是一个橡皮概念。连接到对等方尚未关闭的套接字的流的大小是多少?流不是数组。

标签: c++ stream size buffer string-length


【解决方案1】:

您可能指的是foo.rdbuf()->in_avail(),但您错误地假设流始终将其全部内容保存在缓冲区中,而对于文件流之类的情况则不然。

例如,GCC 使用长度为 BUFSIZ 的缓冲区,该缓冲区至少为 256 字节(在我的系统上为 1024),因此任何大于该长度的文件都不能完全保存在 basic_filebuf 的缓冲区中。

没有可移植的方法来获取流的真实大小,例如,由于 EOL 转换,在 Windows 上以文本模式打开的流不会为您提供流中的实际字节数。流的设计目的是在您读完之前一直读取,这取决于您尝试对流执行的操作,可能会有更好的方法。

任何介绍性 C++ 的书都会告诉您源代码,但这是标准中的相关措辞

[streambuf.reqts]

每个序列的特征是三个指针,如果非空,它们都指向同一个charT 数组对象。数组对象在任何时候都表示序列中的一个(子)字符序列

【讨论】:

  • 啊,就像我发布那个答案一样添加:) 你能发布一个不包含整个缓冲区的rdbuf 的来源吗?
【解决方案2】:

花时间回顾我的记忆,它又回到了我的脑海:

bar = foo.rdbuf()->in_avail();

你可以在这里看到一个活生生的例子:http://coliru.stacked-crooked.com/a/66b6182627aebbe6


this comment相反,此适用于任何C++流,因为它们all inherit from ios提供rdbuf

【讨论】:

  • 这没有得到流的大小。它确实获得了读取缓冲区中内容的大小,这可能是流的大小,也可能不是流的大小,如果流甚至可以说有大小的概念的话。网络或压缩文件流呢?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-05-20
  • 1970-01-01
  • 2015-02-22
  • 2013-11-19
  • 2014-04-07
  • 1970-01-01
  • 2015-03-28
相关资源
最近更新 更多