Skip to content

Instantly share code, notes, and snippets.

@duncansmart
Created August 31, 2022 14:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save duncansmart/8971dc1e7d2c4411f25a7d0e98320b22 to your computer and use it in GitHub Desktop.
Save duncansmart/8971dc1e7d2c4411f25a7d0e98320b22 to your computer and use it in GitHub Desktop.
Stream that starts off backed by MemoryStream but after threshold will switch to file-backed temp-file stream
using System;
using System.IO;
class SmartStream : Stream
{
int _maxMemorySize;
Stream _stream = new MemoryStream();
public SmartStream(int maxMemorySize)
{
_maxMemorySize = maxMemorySize;
}
public override void Write(byte[] buffer, int offset, int count)
{
_stream.Write(buffer, offset, count);
if (_stream is MemoryStream && _stream.Length > _maxMemorySize)
switchToTempFile();
}
void switchToTempFile()
{
var tempFile = new FileStream(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()), FileMode.Create, FileAccess.ReadWrite, FileShare.Read | FileShare.Delete, 4096, FileOptions.DeleteOnClose);
var streamPos = _stream.Position;
_stream.Position = 0;
_stream.CopyTo(tempFile);
_stream.Dispose();
tempFile.Position = streamPos;
_stream = tempFile;
}
#region Wrappers
public override bool CanRead => _stream.CanRead;
public override bool CanSeek => _stream.CanSeek;
public override bool CanWrite => _stream.CanWrite;
public override long Length => _stream.Length;
public override long Position { get => _stream.Position; set => _stream.Position = value; }
public override void Flush() => _stream.Flush();
public override int Read(byte[] buffer, int offset, int count) => _stream.Read(buffer, offset, count);
public override long Seek(long offset, SeekOrigin origin) => _stream.Seek(offset, origin);
public override void SetLength(long value) => _stream.SetLength(value);
#endregion
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment