Get Stream Size Without Changing Stream Position

时间:2015-07-28 23:40:12

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

The way of getting the size of a stream that I'm familiar with involves doing:

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

But I'd rather not move the stream's position! It obviously already actually knows the start and endpoints of it's buffer, so why can't I just directly access that information?

Somewhere in the recesses of my memory I think there is a way to get this from the stream's ios or ios_base. But I just can't remember. Can someone else recall how to do this?

2 个答案:

答案 0 :(得分:3)

What you're probably referring to is window, but you have made the incorrect assumption that a stream always holds its entire contents in the buffer, which isn't going to be the case for things like file streams.

GCC for instance uses a buffer of length foo.rdbuf()->in_avail() which will be at least 256 bytes (it's 1024 on my system), so any file larger than that cannot be held entirely in a BUFSIZ's buffer.

There's no portable way to get the true size of a stream, for instance a stream opened in text mode on windows won't give you the actual number of bytes in the stream because of EOL conversion. Streams are designed to be read from until you hit the end, depending on what you're trying to do with the stream there may be a better way.

Source-wise any introductory C++ book will tell you as much, but here's the relevant wording in the standard

[streambuf.reqts]

Each sequence is characterized by three pointers which, if non-null, all point into the same basic_filebuf array object. The array object represents, at any moment, a (sub)sequence of characters from the sequence.

答案 1 :(得分:-2)

Took the time to review my memory and it came back to me:

volatile

You can see a live example here: http://coliru.stacked-crooked.com/a/66b6182627aebbe6


Contrary to this comment this will work for any C++ stream because they all inherit from ios which provides rdbuf.

enter image description here