Created
October 30, 2011 00:18
-
-
Save badmotorfinger/1325286 to your computer and use it in GitHub Desktop.
A collection of streams that can be read as one continuous stream
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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