Skip to content

yigolden/PooledGrowableBufferHelper

Repository files navigation

PooledGrowableBufferHelper

A simple library providing reusable MemoryStream implementation and IBufferWriter<byte> implementation. It is suitable for storing temporary byte stream.

The underlying buffer is rented from ArrayPool<byte>.Shared.

Get Started

Install the latest version from NuGet. (.NET Frameword 4.6+ and .NET Standard 2.0+ are supported.)

Install-Package PooledGrowableBufferHelper

Features

  • Implements a MemoryStream-like reusable stream, whose underlying buffer is dynamically rented from ArrayPool<byte>.Shared when more space is needed and returned when Close/Dispose is called.
  • Uses a linked list to track buffers rented for a stream instance.
  • Implements IBufferWriter<byte> interface, which can be used to append data to the end of the stream.
  • Provides a ReadOnlySequence<byte> view over the content in the stream.

Examples

Use as a temporary buffer (like a MemoryStream)

using (PooledMemoryStream ms = PooledMemoryStreamManager.Shared.GetStream())
{
    ms.Write(buffer1, 0, 12);
    ms.Write(buffer2, 0, 12);

    // Seeking to the begining of the stream is very cheep.
    // However, seeking to other random position may not be.
    ms.Seek(0, SeekOrigin.Begin);

    await ms.CopyToAsync(reaponse.Body);
}
// Please make sure Close/Dispose is called so that rented buffer can be returned to the pool

Use as a IBufferWriter<byte>

using (PooledMemoryStream ms = PooledMemoryStreamManager.Shared.GetStream())
{
    IBufferWriter<byte> writer = ms;

    Span<byte> span = writer.GetSpan(16);
    span[0] = 'A';
    ...
    span[11] = 'a';
    writer.Advance(12);

    // When swithing usage from IBufferWriter-base API to stream-based API, make sure Advance is called and no buffer is acquired though GetMemory/GetSpan 
    // When swithing usage from stream-based API to IBufferWriter-base API, make sture the position is at the end of the stream.
    byte[] arr = ms.ToArray[];
}

Use ReadOnlySequence<byte> as a view over the buffer

using (PooledMemoryStream ms = PooledMemoryStreamManager.Shared.GetStream())
{
    ms.Write(buffer1, 0, 12);

    ReadOnlySequence<byte> sequence = ms.ToReadOnlySequence();

    // Don't mutate the content when working with ReadOnlySequence<byte>
}

Use as MemoryStream

If you have a function that accept MemoryStream instad of Stream, you can call AsMemoryStream to acquire a MemoryStream wrapper of the original stream.

using (PooledMemoryStream ms = PooledMemoryStreamManager.Shared.GetStream())
{
    MemoryStream s = ms.AsMemoryStream(leaveOpen: true);

    SomeFunction(s);
}

void SomeFunction(MemoryStream ms)
{
    ...
}

About

A simple library providing reusable MemoryStream implementation and IBufferWriter<byte> implementation. It is suitable for storing temporary byte stream.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages