Namespace: System.Net.Security

DelegatingStream Class

Represents a stream that delegates its operations to another stream.

Inheritance hierarchy

Object
Stream
DelegatingStream

Constructors

Name Description
DelegatingStream(Stream) Initializes a new instance of the DelegatingStream class.

Properties

Name Description
CanRead Gets a value indicating whether the stream supports reading.
CanSeek Gets a value indicating whether the stream supports seeking.
CanWrite Gets a value indicating whether the stream supports writing.
Length Gets the length in bytes of the stream.
Position Gets or sets the position within the current stream.

Methods

Name Description Overrides
BeginRead(Byte[], Int32, Int32, AsyncCallback, Object) Asynchronously reads from the current stream and advances the position within the stream by the number of bytes read. Stream.BeginRead
BeginWrite(Byte[], Int32, Int32, AsyncCallback, Object) Asynchronously writes to the current stream and advances the position within the stream by the number of bytes written. Stream.BeginWrite
Dispose() Releases the unmanaged resources that are used by the current instance of the DelegatingStream class and optionally releases the managed resources. Stream.Dispose
EndRead(IAsyncResult) Waits for the pending asynchronous read to complete. Stream.EndRead
EndWrite(IAsyncResult) Ends a pending asynchronous write. Stream.EndWrite
Flush() Clears all buffers for this stream and causes any buffered data to be written to the underlying devices. Stream.Flush
Read(Byte[], Int32, Int32) Reads a sequence of bytes from the current stream and advances the position within the stream by the number of bytes read. Stream.Read
Seek(Int64, SeekOrigin) Sets the position within the current stream. Stream.Seek
SetLength(Int64) Sets the length of the current stream. Stream.SetLength
Write(Byte[], Int32, Int32) Writes a sequence of bytes to the current stream and advances the position within the stream by the number of bytes written. Stream.Write

Remarks

The DelegatingStream class is an abstract base class that provides a foundation for creating custom stream types. It encapsulates a target stream and forwards all stream operations to that target stream. This is useful for decorators or wrapper classes that add functionality to an existing stream without completely reimplementing its behavior.

For example, you might create a derived class that logs all read or write operations, encrypts or decrypts data as it passes through, or applies compression/decompression.

Example

Creating a Logging Stream Wrapper

This example shows how to create a simple stream that logs read and write operations to the console.

using System; using System.IO; using System.Text; public class LoggingStream : DelegatingStream { private readonly string _name; public LoggingStream(Stream innerStream, string name) : base(innerStream) { _name = name ?? "UnnamedStream"; } public override int Read(byte[] buffer, int offset, int count) { int bytesRead = base.Read(buffer, offset, count); if (bytesRead > 0) { string data = Encoding.UTF8.GetString(buffer, offset, bytesRead); Console.WriteLine($"[{_name}] Read {bytesRead} bytes: \"{data}\""); } return bytesRead; } public override void Write(byte[] buffer, int offset, int count) { string data = Encoding.UTF8.GetString(buffer, offset, count); Console.WriteLine($"[{_name}] Writing {count} bytes: \"{data}\""); base.Write(buffer, offset, count); } public override void Flush() { Console.WriteLine($"[{_name}] Flushing stream."); base.Flush(); } public override bool CanRead => base.CanRead; public override bool CanSeek => base.CanSeek; public override bool CanWrite => base.CanWrite; public override long Length => base.Length; public override long Position { get => base.Position; set => base.Position = value; } public override void SetLength(long value) { Console.WriteLine($"[{_name}] Setting length to {value}."); base.SetLength(value); } public override long Seek(long offset, SeekOrigin origin) { long newPosition = base.Seek(offset, origin); Console.WriteLine($"[{_name}] Seeking to position {newPosition}."); return newPosition; } } public class ExampleUsage { public static void Main(string[] args) { using (var memoryStream = new MemoryStream()) { var loggingStream = new LoggingStream(memoryStream, "MyLoggingStream"); string message = "Hello, DelegatingStream!"; byte[] messageBytes = Encoding.UTF8.GetBytes(message); loggingStream.Write(messageBytes, 0, messageBytes.Length); loggingStream.Flush(); // Reset stream position to read memoryStream.Seek(0, SeekOrigin.Begin); byte[] readBuffer = new byte[messageBytes.Length]; int bytesRead = loggingStream.Read(readBuffer, 0, readBuffer.Length); Console.WriteLine($"Read from stream: {Encoding.UTF8.GetString(readBuffer, 0, bytesRead)}"); } } }

Requirements

.NET Framework Supported Versions

Supported in: .NET Framework 4.5, .NET Framework 4.5.1, .NET Framework 4.5.2, .NET Framework 4.6, .NET Framework 4.6.1, .NET Framework 4.6.2, .NET Framework 4.7, .NET Framework 4.7.1, .NET Framework 4.7.2, .NET Framework 4.8

.NET Standard Supported Versions

Supported in: .NET Standard 2.0

.NET Supported Versions

Supported in: .NET Core 1.0, .NET Core 1.1, .NET Core 2.0, .NET Core 2.1, .NET Core 2.2, .NET Core 3.0, .NET Core 3.1, .NET 5, .NET 6, .NET 7, .NET 8