Skip to content

Instantly share code, notes, and snippets.

@badmotorfinger
Created October 30, 2011 00:18
Show Gist options
  • Save badmotorfinger/1325286 to your computer and use it in GitHub Desktop.
Save badmotorfinger/1325286 to your computer and use it in GitHub Desktop.
A collection of streams that can be read as one continuous stream
namespace Mvc.ResourceLoader.Util {
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
public class JoinedStreamReader : Stream {
long _pos = 0;
long _length = 0;
IEnumerable<Stream> _streams;
public JoinedStreamReader(IEnumerable<Stream> streams) {
if (streams == null)
throw new ArgumentNullException("streams");
_streams = streams;
_length =
_streams.Aggregate(new long(), (l, stream) => l += stream.Length);
}
public override void Close() {
foreach (var item in _streams)
item.Close();
}
public override bool CanRead {
get { return true; }
}
public override bool CanSeek {
get { return false; }
}
public override bool CanWrite {
get { return false; }
}
public override void Flush() {
throw new InvalidOperationException("Can not flush a stream that does not support writing.");
}
public override long Length {
get { return _length; }
}
public override long Position {
get {
return _pos;
}
set {
if (value < 0)
throw new ArgumentOutOfRangeException("value", "Non-negative number required");
if (value == 0)
foreach (var item in _streams)
item.Position = 0;
_pos = value;
}
}
public override int Read(byte[] buffer, int offset, int count) {
if (count > buffer.Length)
throw new ArgumentException("Offset and length were out of bounds for the array or count is greater than the number of elements from index to the end of the source collection.");
int bytesRead = 0;
int numberOfBytesToRead = count;
long streamLengthAggregate = 0;
foreach (var stream in _streams) {
streamLengthAggregate += stream.Length;
if (_pos > streamLengthAggregate)
continue;
bytesRead += stream.Read(buffer, offset, numberOfBytesToRead);
if (bytesRead < numberOfBytesToRead) {
numberOfBytesToRead -= bytesRead;
offset += bytesRead;
continue;
}
break;
}
_pos += bytesRead;
return bytesRead;
}
public override long Seek(long offset, SeekOrigin origin) {
throw new NotSupportedException();
}
public override void SetLength(long value) {
throw new NotSupportedException();
}
public override void Write(byte[] buffer, int offset, int count) {
throw new NotSupportedException();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment