DelegatingStream Class
Represents a stream that delegates its operations to another stream.
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