BufferedStream Class

 

Adds a buffering layer to read and write operations on another stream. This class cannot be inherited.

Namespace:   System.IO
Assembly:  mscorlib (in mscorlib.dll)

System::Object
  System::MarshalByRefObject
    System.IO::Stream
      System.IO::BufferedStream

[ComVisibleAttribute(true)]
public ref class BufferedStream sealed : Stream

NameDescription
System_CAPS_pubmethodBufferedStream(Stream^)

Initializes a new instance of the BufferedStream class with a default buffer size of 4096 bytes.

System_CAPS_pubmethodBufferedStream(Stream^, Int32)

Initializes a new instance of the BufferedStream class with the specified buffer size.

NameDescription
System_CAPS_pubpropertyCanRead

Gets a value indicating whether the current stream supports reading.(Overrides Stream::CanRead.)

System_CAPS_pubpropertyCanSeek

Gets a value indicating whether the current stream supports seeking.(Overrides Stream::CanSeek.)

System_CAPS_pubpropertyCanTimeout

Gets a value that determines whether the current stream can time out.(Inherited from Stream.)

System_CAPS_pubpropertyCanWrite

Gets a value indicating whether the current stream supports writing.(Overrides Stream::CanWrite.)

System_CAPS_pubpropertyLength

Gets the stream length in bytes.(Overrides Stream::Length.)

System_CAPS_pubpropertyPosition

Gets the position within the current stream.(Overrides Stream::Position.)

System_CAPS_pubpropertyReadTimeout

Gets or sets a value, in miliseconds, that determines how long the stream will attempt to read before timing out. (Inherited from Stream.)

System_CAPS_pubpropertyWriteTimeout

Gets or sets a value, in miliseconds, that determines how long the stream will attempt to write before timing out. (Inherited from Stream.)

NameDescription
System_CAPS_pubmethodBeginRead(array<Byte>^, Int32, Int32, AsyncCallback^, Object^)

Begins an asynchronous read operation. (Consider using ReadAsync instead; see the Remarks section.)(Overrides Stream::BeginRead(array<Byte>^, Int32, Int32, AsyncCallback^, Object^).)

System_CAPS_pubmethodBeginWrite(array<Byte>^, Int32, Int32, AsyncCallback^, Object^)

Begins an asynchronous write operation. (Consider using WriteAsync instead; see the Remarks section.)(Overrides Stream::BeginWrite(array<Byte>^, Int32, Int32, AsyncCallback^, Object^).)

System_CAPS_pubmethodClose()

Closes the current stream and releases any resources (such as sockets and file handles) associated with the current stream. Instead of calling this method, ensure that the stream is properly disposed.(Inherited from Stream.)

System_CAPS_pubmethodCopyTo(Stream^)

Reads the bytes from the current stream and writes them to another stream.(Inherited from Stream.)

System_CAPS_pubmethodCopyTo(Stream^, Int32)

Reads the bytes from the current stream and writes them to another stream, using a specified buffer size.(Inherited from Stream.)

System_CAPS_pubmethodCopyToAsync(Stream^)

Asynchronously reads the bytes from the current stream and writes them to another stream.(Inherited from Stream.)

System_CAPS_pubmethodCopyToAsync(Stream^, Int32)

Asynchronously reads the bytes from the current stream and writes them to another stream, using a specified buffer size.(Inherited from Stream.)

System_CAPS_pubmethodCopyToAsync(Stream^, Int32, CancellationToken)

Asynchronously reads the bytes from the current stream and writes them to another stream, using a specified buffer size and cancellation token.(Inherited from Stream.)

System_CAPS_pubmethodCreateObjRef(Type^)

Creates an object that contains all the relevant information required to generate a proxy used to communicate with a remote object.(Inherited from MarshalByRefObject.)

System_CAPS_pubmethodDispose()

Releases all resources used by the Stream.(Inherited from Stream.)

System_CAPS_pubmethodEndRead(IAsyncResult^)

Waits for the pending asynchronous read operation to complete. (Consider using ReadAsync instead; see the Remarks section.)(Overrides Stream::EndRead(IAsyncResult^).)

System_CAPS_pubmethodEndWrite(IAsyncResult^)

Ends an asynchronous write operation and blocks until the I/O operation is complete. (Consider using WriteAsync instead; see the Remarks section.)(Overrides Stream::EndWrite(IAsyncResult^).)

System_CAPS_pubmethodEquals(Object^)

Determines whether the specified object is equal to the current object.(Inherited from Object.)

System_CAPS_pubmethodFlush()

Clears all buffers for this stream and causes any buffered data to be written to the underlying device.(Overrides Stream::Flush().)

System_CAPS_pubmethodFlushAsync()

Asynchronously clears all buffers for this stream and causes any buffered data to be written to the underlying device.(Inherited from Stream.)

System_CAPS_pubmethodFlushAsync(CancellationToken)

Asynchronously clears all buffers for this stream, causes any buffered data to be written to the underlying device, and monitors cancellation requests.(Overrides Stream::FlushAsync(CancellationToken).)

System_CAPS_pubmethodGetHashCode()

Serves as the default hash function. (Inherited from Object.)

System_CAPS_pubmethodGetLifetimeService()

Retrieves the current lifetime service object that controls the lifetime policy for this instance.(Inherited from MarshalByRefObject.)

System_CAPS_pubmethodGetType()

Gets the Type of the current instance.(Inherited from Object.)

System_CAPS_pubmethodInitializeLifetimeService()

Obtains a lifetime service object to control the lifetime policy for this instance.(Inherited from MarshalByRefObject.)

System_CAPS_pubmethodRead(array<Byte>^, Int32, Int32)

Copies bytes from the current buffered stream to an array.(Overrides Stream::Read(array<Byte>^, Int32, Int32).)

System_CAPS_pubmethodReadAsync(array<Byte>^, Int32, Int32)

Asynchronously reads a sequence of bytes from the current stream and advances the position within the stream by the number of bytes read.(Inherited from Stream.)

System_CAPS_pubmethodReadAsync(array<Byte>^, Int32, Int32, CancellationToken)

Asynchronously reads a sequence of bytes from the current stream, advances the position within the stream by the number of bytes read, and monitors cancellation requests.(Overrides Stream::ReadAsync(array<Byte>^, Int32, Int32, CancellationToken).)

System_CAPS_pubmethodReadByte()

Reads a byte from the underlying stream and returns the byte cast to an int, or returns -1 if reading from the end of the stream.(Overrides Stream::ReadByte().)

System_CAPS_pubmethodSeek(Int64, SeekOrigin)

Sets the position within the current buffered stream.(Overrides Stream::Seek(Int64, SeekOrigin).)

System_CAPS_pubmethodSetLength(Int64)

Sets the length of the buffered stream.(Overrides Stream::SetLength(Int64).)

System_CAPS_pubmethodToString()

Returns a string that represents the current object.(Inherited from Object.)

System_CAPS_pubmethodWrite(array<Byte>^, Int32, Int32)

Copies bytes to the buffered stream and advances the current position within the buffered stream by the number of bytes written.(Overrides Stream::Write(array<Byte>^, Int32, Int32).)

System_CAPS_pubmethodWriteAsync(array<Byte>^, Int32, Int32)

Asynchronously writes a sequence of bytes to the current stream and advances the current position within this stream by the number of bytes written.(Inherited from Stream.)

System_CAPS_pubmethodWriteAsync(array<Byte>^, Int32, Int32, CancellationToken)

Asynchronously writes a sequence of bytes to the current stream, advances the current position within this stream by the number of bytes written, and monitors cancellation requests.(Overrides Stream::WriteAsync(array<Byte>^, Int32, Int32, CancellationToken).)

System_CAPS_pubmethodWriteByte(Byte)

Writes a byte to the current position in the buffered stream.(Overrides Stream::WriteByte(Byte).)

A buffer is a block of bytes in memory used to cache data, thereby reducing the number of calls to the operating system. Buffers improve read and write performance. A buffer can be used for either reading or writing, but never both simultaneously. The Read and Write methods of BufferedStream automatically maintain the buffer.

System_CAPS_importantImportant

This type implements the IDisposable interface. When you have finished using the type, you should dispose of it either directly or indirectly. To dispose of the type directly, call its Dispose method in a try/catch block. To dispose of it indirectly, use a language construct such as using (in C#) or Using (in Visual Basic). For more information, see the “Using an Object that Implements IDisposable” section in the IDisposable interface topic.

BufferedStream can be composed around certain types of streams. It provides implementations for reading and writing bytes to an underlying data source or repository. Use BinaryReader and BinaryWriter for reading and writing other data types. BufferedStream is designed to prevent the buffer from slowing down input and output when the buffer is not needed. If you always read and write for sizes greater than the internal buffer size, then BufferedStream might not even allocate the internal buffer. BufferedStream also buffers reads and writes in a shared buffer. It is assumed that you will almost always be doing a series of reads or writes, but rarely alternate between the two of them.

The following code examples show how to use the BufferedStream class over the NetworkStream class to increase the performance of certain I/O operations. Start the server on a remote computer before starting the client. Specify the remote computer name as a command-line argument when starting the client. Vary the dataArraySize and streamBufferSize constants to view their effect on performance.

The first example shows the code that runs on the client, and the second example shows the code that runs on the server.

Example 1: Code that runs on the client

#using <system.dll>

using namespace System;
using namespace System::IO;
using namespace System::Globalization;
using namespace System::Net;
using namespace System::Net::Sockets;
static const int streamBufferSize = 1000;
public ref class Client
{
private:
   literal int dataArraySize = 100;
   literal int numberOfLoops = 10000;
   Client(){}


public:
   static void ReceiveData( Stream^ netStream, Stream^ bufStream )
   {
      DateTime startTime;
      Double networkTime;
      Double bufferedTime = 0;
      int bytesReceived = 0;
      array<Byte>^receivedData = gcnew array<Byte>(dataArraySize);

      // Receive data using the NetworkStream.
      Console::WriteLine( "Receiving data using NetworkStream." );
      startTime = DateTime::Now;
      while ( bytesReceived < numberOfLoops * receivedData->Length )
      {
         bytesReceived += netStream->Read( receivedData, 0, receivedData->Length );
      }

      networkTime = (DateTime::Now - startTime).TotalSeconds;
      Console::WriteLine( "{0} bytes received in {1} seconds.\n", bytesReceived.ToString(), networkTime.ToString(  "F1" ) );

      // Receive data using the BufferedStream.
      Console::WriteLine(  "Receiving data using BufferedStream." );
      bytesReceived = 0;
      startTime = DateTime::Now;
      while ( bytesReceived < numberOfLoops * receivedData->Length )
      {
         bytesReceived += bufStream->Read( receivedData, 0, receivedData->Length );
      }

      bufferedTime = (DateTime::Now - startTime).TotalSeconds;
      Console::WriteLine( "{0} bytes received in {1} seconds.\n", bytesReceived.ToString(), bufferedTime.ToString(  "F1" ) );

      // Print the ratio of read times.
      Console::WriteLine( "Receiving data using the buffered "
      "network stream was {0} {1} than using the network "
      "stream alone.", (networkTime / bufferedTime).ToString(  "P0" ), bufferedTime < networkTime ? (String^)"faster" : "slower" );
   }

   static void SendData( Stream^ netStream, Stream^ bufStream )
   {
      DateTime startTime;
      Double networkTime;
      Double bufferedTime;

      // Create random data to send to the server.
      array<Byte>^dataToSend = gcnew array<Byte>(dataArraySize);
      (gcnew Random)->NextBytes( dataToSend );

      // Send the data using the NetworkStream.
      Console::WriteLine( "Sending data using NetworkStream." );
      startTime = DateTime::Now;
      for ( int i = 0; i < numberOfLoops; i++ )
      {
         netStream->Write( dataToSend, 0, dataToSend->Length );

      }
      networkTime = (DateTime::Now - startTime).TotalSeconds;
      Console::WriteLine( "{0} bytes sent in {1} seconds.\n", (numberOfLoops * dataToSend->Length).ToString(), networkTime.ToString(  "F1" ) );

      // Send the data using the BufferedStream.
      Console::WriteLine( "Sending data using BufferedStream." );
      startTime = DateTime::Now;
      for ( int i = 0; i < numberOfLoops; i++ )
      {
         bufStream->Write( dataToSend, 0, dataToSend->Length );

      }
      bufStream->Flush();
      bufferedTime = (DateTime::Now - startTime).TotalSeconds;
      Console::WriteLine( "{0} bytes sent in {1} seconds.\n", (numberOfLoops * dataToSend->Length).ToString(), bufferedTime.ToString(  "F1" ) );

      // Print the ratio of write times.
      Console::WriteLine( "Sending data using the buffered "
      "network stream was {0} {1} than using the network "
      "stream alone.\n", (networkTime / bufferedTime).ToString(  "P0" ), bufferedTime < networkTime ? (String^)"faster" : "slower" );
   }

};

int main( int argc, char *argv[] )
{

   // Check that an argument was specified when the 
   // program was invoked.
   if ( argc == 1 )
   {
      Console::WriteLine( "Error: The name of the host computer"
      " must be specified when the program is invoked." );
      return  -1;
   }

   String^ remoteName = gcnew String( argv[ 1 ] );

   // Create the underlying socket and connect to the server.
   Socket^ clientSocket = gcnew Socket( AddressFamily::InterNetwork,SocketType::Stream,ProtocolType::Tcp );
   clientSocket->Connect( gcnew IPEndPoint( Dns::Resolve( remoteName )->AddressList[ 0 ],1800 ) );
   Console::WriteLine(  "Client is connected.\n" );

   // Create a NetworkStream that owns clientSocket and 
   // then create a BufferedStream on top of the NetworkStream.
   NetworkStream^ netStream = gcnew NetworkStream( clientSocket,true );
   BufferedStream^ bufStream = gcnew BufferedStream( netStream,streamBufferSize );

   try
   {

      // Check whether the underlying stream supports seeking.
      Console::WriteLine( "NetworkStream {0} seeking.\n", bufStream->CanSeek ? (String^)"supports" : "does not support" );

      // Send and receive data.
      if ( bufStream->CanWrite )
      {
         Client::SendData( netStream, bufStream );
      }

      if ( bufStream->CanRead )
      {
         Client::ReceiveData( netStream, bufStream );
      }

   }
   finally
   {

      // When bufStream is closed, netStream is in turn closed,
      // which in turn shuts down the connection and closes
      // clientSocket.
      Console::WriteLine( "\nShutting down connection." );
      bufStream->Close();

   }

}

Example 2: Code that runs on the server

#using <system.dll>

using namespace System;
using namespace System::Net;
using namespace System::Net::Sockets;
int main()
{

   // This is a Windows Sockets 2 error code.
   const int WSAETIMEDOUT = 10060;
   Socket^ serverSocket;
   int bytesReceived;
   int totalReceived = 0;
   array<Byte>^receivedData = gcnew array<Byte>(2000000);

   // Create random data to send to the client.
   array<Byte>^dataToSend = gcnew array<Byte>(2000000);
   (gcnew Random)->NextBytes( dataToSend );
   IPAddress^ ipAddress = Dns::Resolve( Dns::GetHostName() )->AddressList[ 0 ];
   IPEndPoint^ ipEndpoint = gcnew IPEndPoint( ipAddress,1800 );

   // Create a socket and listen for incoming connections.
   Socket^ listenSocket = gcnew Socket( AddressFamily::InterNetwork,SocketType::Stream,ProtocolType::Tcp );
   try
   {
      listenSocket->Bind( ipEndpoint );
      listenSocket->Listen( 1 );

      // Accept a connection and create a socket to handle it.
      serverSocket = listenSocket->Accept();
      Console::WriteLine( "Server is connected.\n" );
   }
   finally
   {
      listenSocket->Close();
   }

   try
   {

      // Send data to the client.
      Console::Write( "Sending data ... " );
      int bytesSent = serverSocket->Send( dataToSend, 0, dataToSend->Length, SocketFlags::None );
      Console::WriteLine( "{0} bytes sent.\n", bytesSent.ToString() );

      // Set the timeout for receiving data to 2 seconds.
      serverSocket->SetSocketOption( SocketOptionLevel::Socket, SocketOptionName::ReceiveTimeout, 2000 );

      // Receive data from the client.
      Console::Write( "Receiving data ... " );
      try
      {
         do
         {
            bytesReceived = serverSocket->Receive( receivedData, 0, receivedData->Length, SocketFlags::None );
            totalReceived += bytesReceived;
         }
         while ( bytesReceived != 0 );
      }
      catch ( SocketException^ e ) 
      {
         if ( e->ErrorCode == WSAETIMEDOUT )
         {

            // Data was not received within the given time.
            // Assume that the transmission has ended.
         }
         else
         {
            Console::WriteLine( "{0}: {1}\n", e->GetType()->Name, e->Message );
         }
      }
      finally
      {
         Console::WriteLine( "{0} bytes received.\n", totalReceived.ToString() );
      }

   }
   finally
   {
      serverSocket->Shutdown( SocketShutdown::Both );
      Console::WriteLine( "Connection shut down." );
      serverSocket->Close();
   }

}

.NET Framework
Available since 1.1

Any public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe.

Return to top
Show: