Over the years of Windows programming, I have quite often needed a
MemoryStream class to handle various text and binary data streaming tasks. I have also needed to implement my own
IStream interface, which of course must be backed by a
MemoryStream. So I wrote the
CStream class provided in this article. Since then, I have used this class in almost every project I have done. Often, I find I need to build
strings a bit at a time.
CStream makes a perfect
StringBuilder class. You'll never need to worry about memory allocation, no matter how large the
stream grows because
CStream allocates new memory as needed.
The key feature of
CStream is that it takes care of growing the internal buffer as needed. And the key to high performance is using
VirtualAlloc. This is a very fast memory allocation function created just for this sort of situation where memory is reallocated often.
CStream implements the COM
IStream interfaces*. This means you can use it wherever an
IStream is needed. In addition to the
IStream interface, there are many helper/access methods which give access to the internal buffer for example.
CStream is implemented in Stream.h and Stream.cpp.
IStream interface is not fully implemented - only the most commonly used methods.
Suppose you need a
StringBuilder because you need to build up a
string a bit at a time. Here's the code:
strm << "This is ";
strm << "an example ";
strm << "of a multibyte ";
strm << "string builder ";
strm << "using CStream";
strm << char(0);
PSTR pszString = (PTSTR) strm.GetBuf();
You only need to declare the
CStream and begin writing to it. You can use the overloaded
<< operator or
CStream::Write. Be sure to write a final
NULL terminator before calling
GetBuf returns the internal buffer as a
BYTE* which must be cast to our desired type in this case.
Binary data streaming is accomplished using
CStream::Write, as shown in the following example:
GetModuleFileName( NULL, szFilename, sizeof(szFilename) );
CFile file( szFilename, CFile::modeRead );
while( nRead = file.Read( buf, sizeof(buf) ) )
strm.Write( buf, nRead, NULL );
CStream also has these helper methods:
GetByte: Returns the
Byte at the current position, with the option to advance the current position.
GetCurPos: Returns the current internal position.
GetEndPos: Returns the current end position. This is not the current total allocated size, but rather the highest place in the buffer which has been written to.
SetEndPos: Sets the current end position, resizing the
stream if necessary.
SeekToBegin: Sets the internal position to the beginning of the
SeekToEnd: Sets the internal position to the end of the
Seek: Sets the internal position to the indicated position in the
Reset: Resets the
stream, optionally setting the size.
Text and data streaming are common things to do in programming. This
stream class fills the need quite nicely. I hope you find it to be as useful as I have.
- 8th October, 2009: Initial version