.NET API BrowserSystem.Net.SecurityDelegatingStream

DelegatingStream Class

Represents a stream that delegates its operations to another stream. This class is abstract and serves as a base class for stream decorators that modify or augment the behavior of an underlying stream without directly implementing all stream operations themselves.

C# VB.NET C++
public abstract class DelegatingStream : Stream
Public MustInherit Class DelegatingStream
                    Inherits Stream
public ref class DelegatingStream abstract : public Stream

Inheritance Hierarchy

Inheritance Diagram

Methods

[OverrideAttribute] protected override void Dispose(bool disposing)
Disposes of the resources (except the stream it delegates to) used by the DelegatingStream.
public override void Flush()
Clears all buffers for the current stream and causes any buffered data to be written to the underlying storage.
public override int Read(byte[] buffer, int offset, int count)
Reads a sequence of bytes from the current stream and advances the position within the stream by the number of bytes read.
public override long Seek(long offset, SeekOrigin origin)
Sets the position within the current stream to the specified value.
public override void SetLength(long value)
Sets the length of the current stream.
public override void Write(byte[] buffer, int offset, int count)
Writes a sequence of bytes to the current stream and advances the position within the stream by the number of bytes written.
protected abstract Stream GetStream()
Abstract method that must be overridden by derived classes to return the underlying stream to which operations are delegated.

Properties

public override bool CanRead { get; }
Gets a value indicating whether the current stream supports reading.
public override bool CanSeek { get; }
Gets a value indicating whether the current stream supports seeking.
public override bool CanWrite { get; }
Gets a value indicating whether the current stream supports writing.
public override long Length { get; }
Gets the length in bytes of the stream.
public override long Position { get; set; }
Gets or sets the position within the current stream.

Remarks

The DelegatingStream class is designed to be the base class for custom stream implementations that wrap another stream. Developers can inherit from DelegatingStream and override specific methods (like Read, Write, Flush, etc.) to add custom behavior, such as encryption, compression, logging, or data transformation. The GetStream abstract method must be implemented to provide the underlying stream.

This pattern promotes code reuse and simplifies the creation of complex stream decorators by only requiring implementation of the modified operations, while other operations are automatically delegated to the base class's implementation (which in turn delegates to the underlying stream).

Examples

A common use case is creating a stream that logs all data read from or written to an underlying stream.

using System;
using System.IO;

public class LoggingDelegatingStream : DelegatingStream
{
    private readonly Stream _innerStream;
    private readonly TextWriter _logWriter;

    public LoggingDelegatingStream(Stream innerStream, TextWriter logWriter)
    {
        _innerStream = innerStream ?? throw new ArgumentNullException(nameof(innerStream));
        _logWriter = logWriter ?? throw new ArgumentNullException(nameof(logWriter));
    }

    protected override Stream GetStream()
    {
        return _innerStream;
    }

    public override int Read(byte[] buffer, int offset, int count)
    {
        int bytesRead = base.Read(buffer, offset, count);
        if (bytesRead > 0)
        {
            _logWriter.WriteLine($"Read {bytesRead} bytes.");
            // Optionally log the data itself, e.g., as hex or string
        }
        return bytesRead;
    }

    public override void Write(byte[] buffer, int offset, int count)
    {
        base.Write(buffer, offset, count);
        _logWriter.WriteLine($"Wrote {count} bytes.");
        // Optionally log the data itself
    }

    protected override void Dispose(bool disposing)
    {
        if (disposing)
        {
            // Do NOT dispose of _innerStream here, as it might be managed elsewhere.
            _logWriter?.Dispose(); // Dispose of log writer if it's managed here
        }
        base.Dispose(disposing);
    }
}

See Also