Question

Is there a better way to determine the length of an std::istream than the following:

std::istream* pcStream = GetSomeStream();
pcStream->seekg(0, ios::end);
unsigned int uiLength = pcStream->tellg();

It just seems really wasteful to have to seek to the end of the stream and then seek back to the original position, especially if the stream might be to a file on some slow media like a CD or DVD.

Was it helpful?

Solution

The "best" way is to avoid needing the length :)

  • Not all streams are seekable (For example, imagine an istream on a network socket)
  • The return type from tellg() is not necessarily numeric (the only requirement is that it can be passed back to seekg() to return to the same position)
  • Even if it is numeric, it is not necessarily a number of bytes. For example, it could be a "magic" value meaning "at the end"
  • For fstreams, issues like case and linefeed conversion can screw things up

OTHER TIPS

In order to get the current length / size of a steam I do this:

auto size = strlen(currentStream.str().c_str());

This needs to happen before functions that will set its size to 0 such as move(currentStream).

Have you considered keeping track of the size by using istream::gcount() ?

There was some kind of stream which couldn't get length by calling tellg(). In case of, tellg() may return -1.

You could get stream length by preparing enough sized buffer. I found out how to get length by looking into stream::read function.

const int DATA_SIZE = 1024 * 512;
char buf[DATA_SIZE];  // 1024 * 512 is enough!
std::istream& is = GetSomeStream();
int Len = is.rdbuf()->sgetn(buf, DATA_SIZE);

Above, Len is real data size in istream.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top