views:

223

answers:

3

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 implement that.

Thanks in advance!

+1  A: 

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.")

sbi
A: 

Take a look at the STL implementation:

Google Code Search: sstream

And:

Google Code Search: sstream.tcc

Albert
+1  A: 

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.

Éric Malenfant