Skip to content

Instantly share code, notes, and snippets.

@ramtinak
Created May 21, 2021 13:22
Show Gist options
  • Save ramtinak/14454c854b3bcaabfc317c8595d11d1e to your computer and use it in GitHub Desktop.
Save ramtinak/14454c854b3bcaabfc317c8595d11d1e to your computer and use it in GitHub Desktop.
C# ConcatenatedStream
namespace StreamHelper.Streams
{
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using System.Threading;
public class ConcatenatedStream : Stream
{
Queue<Stream> _streams; // You can use Stack as well
public ConcatenatedStream(params Stream[] streams) =>
_streams = new Queue<Stream>(streams);
~ConcatenatedStream()
{
_streams = null;
Dispose(true);
}
public override int Read(byte[] buffer, int offset, int count)
{
int totalBytesRead = ReadAsync(buffer, offset, count).GetAwaiter().GetResult();
return totalBytesRead;
}
public new async Task<int> ReadAsync(byte[] buffer, int offset, int count)
{
int totalBytesRead = 0;
while (count > 0 && _streams.Count > 0)
{
int bytesRead = await _streams.Peek().ReadAsync(buffer, offset, count);
if (bytesRead == 0)
{
_streams.Dequeue().Dispose();
continue;
}
totalBytesRead += bytesRead;
offset += bytesRead;
count -= bytesRead;
}
return totalBytesRead;
}
public new async Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
int totalBytesRead = 0;
while (count > 0 && _streams.Count > 0 && !cancellationToken.IsCancellationRequested)
{
int bytesRead = await _streams.Peek().ReadAsync(buffer, offset, count);
if (bytesRead == 0)
{
_streams.Dequeue().Dispose();
continue;
}
totalBytesRead += bytesRead;
offset += bytesRead;
count -= bytesRead;
}
return totalBytesRead;
}
public override bool CanRead => true;
public override bool CanSeek => false;
public override bool CanWrite => false;
public override void Flush()
{
throw new NotImplementedException();
}
public override long Length
{
get { throw new NotImplementedException(); }
}
public override long Position
{
get
{
throw new NotImplementedException();
}
set
{
throw new NotImplementedException();
}
}
public override long Seek(long offset, SeekOrigin origin)
{
throw new NotImplementedException();
}
public override void SetLength(long value)
{
throw new NotImplementedException();
}
public override void Write(byte[] buffer, int offset, int count)
{
throw new NotImplementedException();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment