Jonathan Mee
Jonathan Mee

Reputation: 38919

Get Stream Size Without Changing Stream Position

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?

Upvotes: 2

Views: 255

Answers (2)

user657267
user657267

Reputation: 20990

What you're probably referring to is foo.rdbuf()->in_avail(), 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 BUFSIZ 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 basic_filebuf'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 charT array object. The array object represents, at any moment, a (sub)sequence of characters from the sequence.

Upvotes: 3

Jonathan Mee
Jonathan Mee

Reputation: 38919

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

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

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

Upvotes: -2

Related Questions