PooledMemoryStream Class

A MemoryStream whose storage is a chain of pooled byte arrays rented from a process-wide pool shared by all instances. The stream also implements IBufferWriter<T> (explicit implementation), so it can be used as a destination for APIs such as Utf8JsonWriter.

public sealed class PooledMemoryStream : MemoryStream, IBufferWriter<byte>

Remarks

Unlike MemoryStream, growing the stream never reallocates and copies a single backing array: new pooled blocks are appended to a chain. Blocks are only ever rented in the discrete sizes configured by PooledMemoryStreamOptions, which keeps the shared pool buckets small and reusable.

Buffers (including the array returned by PooledMemoryStream.GetBuffer / PooledMemoryStream.TryGetBuffer, and the spans returned by the IBufferWriter<T> members) are owned by the stream and are returned to the pool when the stream is disposed. Accessing them after the stream is disposed is undefined behavior.

An array returned by PooledMemoryStream.GetBuffer / PooledMemoryStream.TryGetBuffer is never returned to the pool before the stream is disposed, so no other stream can rent it while the caller may still hold it. As with MemoryStream, it stays the stream's storage (shrinking the stream with PooledMemoryStream.SetLength or PooledMemoryStream.Capacity keeps it, so later writes overwrite it) until a later PooledMemoryStream.GetBuffer / PooledMemoryStream.TryGetBuffer call has to consolidate several blocks into a new array; from then on it remains valid but no longer reflects the contents of the stream.

Because the storage is a chain of blocks rather than one array, the stream is not bounded by Array.MaxLength: it can hold as many bytes as memory allows. The members that have to materialize the contents as a single array (PooledMemoryStream.ToArray, PooledMemoryStream.GetBuffer and PooledMemoryStream.TryGetBuffer) are still bounded by it and throw an InvalidOperationException on a longer stream.

This type is not thread-safe; the shared pool is.

Inheritance
MemoryStream PooledMemoryStream
Implements

Constructors

NameDescription
PooledMemoryStream()Initializes a new instance using PooledMemoryStreamOptions.Default.
PooledMemoryStream(PooledMemoryStreamOptions)Initializes a new instance using the specified options.
PooledMemoryStream(PooledMemoryStreamOptions, int)Initializes a new instance using the specified options and reserves at least initialCapacity bytes.
PooledMemoryStream(int)Initializes a new instance using PooledMemoryStreamOptions.Default and reserves at least initialCapacity bytes.

PooledMemoryStream overloads

PooledMemoryStream()

PooledMemoryStream.cs

Initializes a new instance using PooledMemoryStreamOptions.Default.

public PooledMemoryStream()

PooledMemoryStream(PooledMemoryStreamOptions)

PooledMemoryStream.cs

Initializes a new instance using the specified options.

public PooledMemoryStream(PooledMemoryStreamOptions options)
Parameters
options PooledMemoryStreamOptions

PooledMemoryStream(PooledMemoryStreamOptions, int)

PooledMemoryStream.cs

Initializes a new instance using the specified options and reserves at least initialCapacity bytes.

public PooledMemoryStream(PooledMemoryStreamOptions options, int initialCapacity)
Parameters
options PooledMemoryStreamOptions
initialCapacity int

PooledMemoryStream(int)

PooledMemoryStream.cs

Initializes a new instance using PooledMemoryStreamOptions.Default and reserves at least initialCapacity bytes.

public PooledMemoryStream(int initialCapacity)
Parameters
initialCapacity int

Properties

NameDescription
CanReadGets a value indicating whether the current stream supports reading.
CanSeekGets a value indicating whether the current stream supports seeking.
CanWriteGets a value indicating whether the current stream supports writing.
CapacityGets or sets the number of bytes allocated for this stream.
LengthGets the length of the stream in bytes.
PositionGets or sets the current position within the stream.

Gets a value indicating whether the current stream supports reading.

public override bool CanRead { get; }

Property value

bool

Gets a value indicating whether the current stream supports seeking.

public override bool CanSeek { get; }

Property value

bool

Gets a value indicating whether the current stream supports writing.

public override bool CanWrite { get; }

Property value

bool

Gets or sets the number of bytes allocated for this stream.

public override int Capacity { get; set; }

Property value

int

Exceptions

ArgumentOutOfRangeException
A capacity is set that is negative or less than the current length of the stream.
ObjectDisposedException
The current stream is closed.
NotSupportedException
set is invoked on a stream whose capacity cannot be modified.

Gets the length of the stream in bytes.

public override long Length { get; }

Property value

long

Exceptions

ObjectDisposedException
The stream is closed.

Gets or sets the current position within the stream.

public override long Position { get; set; }

Property value

long

Exceptions

ArgumentOutOfRangeException
The position is set to a negative value or a value greater than Int32.MaxValue.
ObjectDisposedException
The stream is closed.

Methods

NameDescription
CopyTo(Stream, int)Reads the bytes from the current memory stream and writes them to another stream, using a specified buffer size.
CopyToAsync(Stream, int, CancellationToken)Asynchronously reads all the bytes from the current stream and writes them to another stream, using a specified buffer size and cancellation token.
Flush()Overrides the Stream.Flush method so that no action is performed.
FlushAsync(CancellationToken)Asynchronously clears all buffers for this stream, and monitors cancellation requests.
GetBuffer()Consolidates the stream contents into a single contiguous array and returns it. The returned array may be larger than PooledMemoryStream.Length; only the first PooledMemoryStream.Length bytes are valid. The array is owned by the stream and is returned to the pool when the stream is disposed, not before: if a later operation replaces it, it stays valid but no longer reflects the contents of the stream.
Read(byte[], int, int)Reads a block of bytes from the current stream and writes the data to a buffer.
Read(Span<byte>)Reads a sequence of bytes from the current memory stream and advances the position within the memory stream by the number of bytes read.
ReadAsync(byte[], int, int, 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.
ReadAsync(Memory<byte>, CancellationToken)Asynchronously reads a sequence of bytes from the current memory stream, writes the sequence into destination, advances the position within the memory stream by the number of bytes read, and monitors cancellation requests.
ReadByte()Reads a byte from the current stream.
Seek(long, SeekOrigin)Sets the position within the current stream to the specified value.
SetLength(long)Sets the length of the current stream to the specified value.
System.Buffers.IBufferWriter<System.Byte>.Advance(int)
System.Buffers.IBufferWriter<System.Byte>.GetMemory(int)Returns a contiguous region of memory to write to. Data written through IBufferWriter<T> is always appended at the end of the stream (after PooledMemoryStream.Length); after Advance, the PooledMemoryStream.Position is moved to the new end.
System.Buffers.IBufferWriter<System.Byte>.GetSpan(int)Returns a Span<T> to write to that is at least the requested size (specified by sizeHint).
ToArray()Returns a new array containing the contents of the stream.
TryGetBuffer(ArraySegment<byte>)Returns the array of unsigned bytes from which this stream was created. The return value indicates whether the conversion succeeded.
Write(byte[], int, int)Writes a block of bytes to the current stream using data read from a buffer.
Write(ReadOnlySpan<byte>)Writes the sequence of bytes contained in source into the current memory stream and advances the current position within this memory stream by the number of bytes written.
WriteAsync(byte[], int, int, 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.
WriteAsync(ReadOnlyMemory<byte>, CancellationToken)Asynchronously writes the sequence of bytes contained in source into the current memory stream, advances the current position within this memory stream by the number of bytes written, and monitors cancellation requests.
WriteByte(byte)Writes a byte to the current stream at the current position.
WriteTo(Stream)Writes the entire contents of this stream to another stream, regardless of the current position.

CopyTo(Stream, int)

PooledMemoryStream.cs

Reads the bytes from the current memory stream and writes them to another stream, using a specified buffer size.

public override void CopyTo(Stream destination, int bufferSize)

Parameters

destination Stream
The stream to which the contents of the current memory stream will be copied.
bufferSize int
The size of the buffer. This value must be greater than zero. The default size is 81920.

Exceptions

ArgumentNullException
destination is null.
ArgumentOutOfRangeException
bufferSize is not a positive number.
ObjectDisposedException
Either the underlying memory stream or the destination stream is closed.
NotSupportedException
The underlying memory stream is unreadable. -or- The destination stream is unwritable.

CopyToAsync(Stream, int, CancellationToken)

PooledMemoryStream.cs

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

public override Task CopyToAsync(Stream destination, int bufferSize, CancellationToken cancellationToken)

Parameters

destination Stream
The stream to which the contents of the current stream will be copied.
bufferSize int
The size, in bytes, of the buffer. This value must be greater than zero.
cancellationToken CancellationToken
The token to monitor for cancellation requests.

Returns

Task A task that represents the asynchronous copy operation.

Exceptions

ArgumentNullException
destination is null.
ArgumentOutOfRangeException
bufferSize is negative or zero.
ObjectDisposedException
Either the current stream or the destination stream is disposed.
NotSupportedException
The current stream does not support reading, or the destination stream does not support writing.
OperationCanceledException
The cancellation token was canceled. This exception is stored into the returned task.

Overrides the Stream.Flush method so that no action is performed.

public override void Flush()

FlushAsync(CancellationToken)

PooledMemoryStream.cs

Asynchronously clears all buffers for this stream, and monitors cancellation requests.

public override Task FlushAsync(CancellationToken cancellationToken)

Parameters

cancellationToken CancellationToken
The token to monitor for cancellation requests.

Returns

Task A task that represents the asynchronous flush operation.

Exceptions

ObjectDisposedException
The stream has been disposed.
OperationCanceledException
The cancellation token was canceled. This exception is stored into the returned task.

Consolidates the stream contents into a single contiguous array and returns it. The returned array may be larger than PooledMemoryStream.Length; only the first PooledMemoryStream.Length bytes are valid. The array is owned by the stream and is returned to the pool when the stream is disposed, not before: if a later operation replaces it, it stays valid but no longer reflects the contents of the stream.

public override byte[] GetBuffer()

Returns

byte[]

Exceptions

InvalidOperationException
The stream is longer than Array.MaxLength.

Read overloads

Read(byte[], int, int)

PooledMemoryStream.cs

Reads a block of bytes from the current stream and writes the data to a buffer.

public override int Read(byte[] buffer, int offset, int count)
Parameters
buffer byte[]
When this method returns, contains the specified byte array with the values between offset and (offset + count - 1) replaced by the characters read from the current stream.
offset int
The zero-based byte offset in buffer at which to begin storing data from the current stream.
count int
The maximum number of bytes to read.
Returns

int The total number of bytes written into the buffer. This can be less than the number of bytes requested if that number of bytes are not currently available, or zero if the end of the stream is reached before any bytes are read.

Exceptions
ArgumentNullException
buffer is null.
ArgumentOutOfRangeException
offset or count is negative.
ArgumentException
offset subtracted from the buffer length is less than count.
ObjectDisposedException
The current stream instance is closed.

Read(Span<byte>)

PooledMemoryStream.cs

Reads a sequence of bytes from the current memory stream and advances the position within the memory stream by the number of bytes read.

public override int Read(Span<byte> buffer)
Parameters
buffer Span<byte>
Returns

int The total number of bytes read into the buffer. This can be less than the number of bytes allocated in the buffer if that many bytes are not currently available, or zero (0) if the end of the memory stream has been reached.

ReadAsync overloads

ReadAsync(byte[], int, int, CancellationToken)

PooledMemoryStream.cs

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.

public override Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
Parameters
buffer byte[]
The buffer to write the data into.
offset int
The byte offset in buffer at which to begin writing data from the stream.
count int
The maximum number of bytes to read.
cancellationToken CancellationToken
The token to monitor for cancellation requests. The default value is CancellationToken.None.
Returns

Task<int> A task that represents the asynchronous read operation. The value of the TResult parameter contains the total number of bytes read into the buffer. The result value can be less than the number of bytes requested if the number of bytes currently available is less than the requested number, or it can be 0 (zero) if the end of the stream has been reached.

Exceptions
ArgumentNullException
buffer is null.
ArgumentOutOfRangeException
offset or count is negative.
ArgumentException
The sum of offset and count is larger than the buffer length.
NotSupportedException
The stream does not support reading.
ObjectDisposedException
The stream has been disposed.
InvalidOperationException
The stream is currently in use by a previous read operation.
OperationCanceledException
The cancellation token was canceled. This exception is stored into the returned task.

ReadAsync(Memory<byte>, CancellationToken)

PooledMemoryStream.cs

Asynchronously reads a sequence of bytes from the current memory stream, writes the sequence into destination, advances the position within the memory stream by the number of bytes read, and monitors cancellation requests.

public override ValueTask<int> ReadAsync(Memory<byte> buffer, CancellationToken cancellationToken = default)
Parameters
buffer Memory<byte>
cancellationToken CancellationToken
The token to monitor for cancellation requests. The default value is CancellationToken.None.
Returns

ValueTask<int> A task that represents the asynchronous read operation. The value of its ValueTask<TResult>.Result property contains the total number of bytes read into the destination. The result value can be less than the number of bytes allocated in destination if that many bytes are not currently available, or it can be 0 (zero) if the end of the memory stream has been reached.

Exceptions
OperationCanceledException
The cancellation token was canceled. This exception is stored into the returned task.

Reads a byte from the current stream.

public override int ReadByte()

Returns

int The byte cast to a Int32, or -1 if the end of the stream has been reached.

Exceptions

ObjectDisposedException
The current stream instance is closed.

Seek(long, SeekOrigin)

PooledMemoryStream.cs

Sets the position within the current stream to the specified value.

public override long Seek(long offset, SeekOrigin loc)

Parameters

offset long
The new position within the stream. This is relative to the loc parameter, and can be positive or negative.
loc SeekOrigin
A value of type SeekOrigin, which acts as the seek reference point.

Returns

long The new position within the stream, calculated by combining the initial reference point and the offset.

Exceptions

IOException
Seeking is attempted before the beginning of the stream.
ArgumentOutOfRangeException
offset is greater than Int32.MaxValue.
ArgumentException
There is an invalid SeekOrigin. -or- offset caused an arithmetic overflow.
ObjectDisposedException
The current stream instance is closed.

SetLength(long)

PooledMemoryStream.cs

Sets the length of the current stream to the specified value.

public override void SetLength(long value)

Parameters

value long
The value at which to set the length.

Exceptions

NotSupportedException
The current stream is not resizable and value is larger than the current capacity. -or- The current stream does not support writing.
ArgumentOutOfRangeException
value is negative or is greater than the maximum length of the MemoryStream, where the maximum length is (Int32.MaxValue - origin), and origin is the index into the underlying buffer at which the stream starts.

System.Buffers.IBufferWriter<System.Byte>.Advance(int)

PooledMemoryStream.cs
void IBufferWriter<byte>.Advance(int count)

Parameters

count int

No documentation is available.

System.Buffers.IBufferWriter<System.Byte>.GetMemory(int)

PooledMemoryStream.cs

Returns a contiguous region of memory to write to. Data written through IBufferWriter<T> is always appended at the end of the stream (after PooledMemoryStream.Length); after Advance, the PooledMemoryStream.Position is moved to the new end.

Memory<byte> IBufferWriter<byte>.GetMemory(int sizeHint)

Parameters

sizeHint int

Returns

Memory<byte>

System.Buffers.IBufferWriter<System.Byte>.GetSpan(int)

PooledMemoryStream.cs

Returns a Span<T> to write to that is at least the requested size (specified by sizeHint).

Span<byte> IBufferWriter<byte>.GetSpan(int sizeHint)

Parameters

sizeHint int
The minimum length of the returned Span<T>. If 0, a non-empty buffer is returned.

Returns

Span<byte> A Span<T> of at least the size sizeHint. If sizeHint is 0, returns a non-empty buffer.

Returns a new array containing the contents of the stream.

public override byte[] ToArray()

Returns

byte[]

Exceptions

InvalidOperationException
The stream is longer than Array.MaxLength.

TryGetBuffer(ArraySegment<byte>)

PooledMemoryStream.cs

Returns the array of unsigned bytes from which this stream was created. The return value indicates whether the conversion succeeded.

public override bool TryGetBuffer(out ArraySegment<byte> buffer)

Parameters

buffer ArraySegment<byte>
When this method returns true, the byte array segment from which this stream was created; when this method returns false, this parameter is set to default.

Returns

bool true if the buffer is exposable; otherwise, false.

Exceptions

InvalidOperationException
The stream is longer than Array.MaxLength.

Write overloads

Write(byte[], int, int)

PooledMemoryStream.cs

Writes a block of bytes to the current stream using data read from a buffer.

public override void Write(byte[] buffer, int offset, int count)
Parameters
buffer byte[]
The buffer to write data from.
offset int
The zero-based byte offset in buffer at which to begin copying bytes to the current stream.
count int
The maximum number of bytes to write.
Exceptions
ArgumentNullException
buffer is null.
NotSupportedException
The stream does not support writing. For additional information see Stream.CanWrite. -or- The current position is closer than count bytes to the end of the stream, and the capacity cannot be modified.
ArgumentException
offset subtracted from the buffer length is less than count.
ArgumentOutOfRangeException
offset or count are negative.
IOException
An I/O error occurs.
ObjectDisposedException
The current stream instance is closed.

Write(ReadOnlySpan<byte>)

PooledMemoryStream.cs

Writes the sequence of bytes contained in source into the current memory stream and advances the current position within this memory stream by the number of bytes written.

public override void Write(ReadOnlySpan<byte> buffer)
Parameters
buffer ReadOnlySpan<byte>

WriteAsync overloads

WriteAsync(byte[], int, int, CancellationToken)

PooledMemoryStream.cs

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.

public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
Parameters
buffer byte[]
The buffer to write data from.
offset int
The zero-based byte offset in buffer from which to begin copying bytes to the stream.
count int
The maximum number of bytes to write.
cancellationToken CancellationToken
The token to monitor for cancellation requests. The default value is CancellationToken.None.
Returns

Task A task that represents the asynchronous write operation.

Exceptions
ArgumentNullException
buffer is null.
ArgumentOutOfRangeException
offset or count is negative.
ArgumentException
The sum of offset and count is larger than the buffer length.
NotSupportedException
The stream does not support writing.
ObjectDisposedException
The stream has been disposed.
InvalidOperationException
The stream is currently in use by a previous write operation.
OperationCanceledException
The cancellation token was canceled. This exception is stored into the returned task.

WriteAsync(ReadOnlyMemory<byte>, CancellationToken)

PooledMemoryStream.cs

Asynchronously writes the sequence of bytes contained in source into the current memory stream, advances the current position within this memory stream by the number of bytes written, and monitors cancellation requests.

public override ValueTask WriteAsync(ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken = default)
Parameters
buffer ReadOnlyMemory<byte>
cancellationToken CancellationToken
The token to monitor for cancellation requests. The default value is CancellationToken.None.
Returns

ValueTask A task that represents the asynchronous write operation.

Exceptions
OperationCanceledException
The cancellation token was canceled. This exception is stored into the returned task.

WriteByte(byte)

PooledMemoryStream.cs

Writes a byte to the current stream at the current position.

public override void WriteByte(byte value)

Parameters

value byte
The byte to write.

Exceptions

NotSupportedException
The stream does not support writing. For additional information see Stream.CanWrite. -or- The current position is at the end of the stream, and the capacity cannot be modified.
ObjectDisposedException
The current stream is closed.

WriteTo(Stream)

PooledMemoryStream.cs

Writes the entire contents of this stream to another stream, regardless of the current position.

public override void WriteTo(Stream stream)

Parameters

stream Stream