In C++, how system implement the buffered stream?
Can someone write some sample code to explain this concept? I know what a buffered stream is used for, but I also would like to know how to开发者_StackOverflow社区 implement that.
Thanks in advance!
You can look into your platform's implementation, the C++ standard or "Standard C++ IOstreams and Locales" by Angelika Langer and Klaus Kreft.
Be prepared for quite a learning curve. Streams are old and a complicated matter. (Francis Glassborow: "I have very few doubts that I/O libraries are amongst the most difficult aspects of any language.")
Veeeery schematically, for an "input" stream:
class BufferedInputStream
{
public:
BufferedInputStream(SomeExternalDevice d)
: m_Device(d),
m_Current(m_Buffer),
m_End(m_Buffer)
{}
char get(){
if (!IsDataAvailableInBuffer()){
ReadAChunkFromDiskAndPutItInBuffer();
}
return PopByteFromBuffer();
}
private:
bool IsDataAvailableInBuffer()const{
return m_Current != m_End;
}
void ReadAChunkFromDiskAndPutItInBuffer(){
// Buffer must be empty
assert(!IsDataAvailableInBuffer());
// Read bytes from the device
bytes_read = Read(m_Device, m_Buffer, BufferSize);
// Reposition the "begin" and "end" pointers
m_Current = m_Buffer;
m_End = m_Buffer + bytes_read;
}
char PopByteFromBuffer(){
assert(IsDataAvailableInBuffer());
return *m_Current++;
}
// For example, an OS file handle
SomeExternalDevice m_Device;
// The buffer itself
char m_Buffer[BufferSize];
// Begin of buffer contents
char* m_Current;
// End of buffer contents
char* m_End;
};
That way, data is read from disk in chunks of the size of the buffer, and most calls to "get()" don't have to end up in calls to the OS, as they can simply return a byte from the buffer.
Take a look at the STL implementation for sstream and sstream.tcc (links to SGI STL implementation).
The base stringstream
class is basic_stringstream
, which implements the basic_iostream
interface.
// [27.7.4] Template class basic_stringstream
/**
* @brief Controlling input and output for std::string.
*
* This class supports reading from and writing to objects of type
* std::basic_string, using the inherited functions from
* std::basic_iostream. To control the associated sequence, an instance
* of std::basic_stringbuf is used, which this page refers to as @c sb.
*/
There is the base class basic_stringbuf
which derives from basic_streambuf
. This holds the buffer.
// [27.7.1] template class basic_stringbuf
/**
* @brief The actual work of input and output (for std::string).
*
* This class associates either or both of its input and output sequences
* with a sequence of characters, which can be initialized from, or made
* available as, a @c std::basic_string. (Paraphrased from [27.7.1]/1.)
*
* For this class, open modes (of type @c ios_base::openmode) have
* @c in set if the input sequence can be read, and @c out set if the
* output sequence can be written.
*/
精彩评论