Let\'s imagine I want to stream three files to a user all in a row, but instead of him handing me a Stream object to push bytes down, I have to hand him a
Untested, but something like:
class StreamEnumerator : Stream
{
private long position;
bool closeStreams;
IEnumerator iterator;
Stream current;
private void EndOfStream() {
if (closeStreams && current != null)
{
current.Close();
current.Dispose();
}
current = null;
}
private Stream Current
{
get {
if(current != null) return current;
if (iterator == null) throw new ObjectDisposedException(GetType().Name);
if (iterator.MoveNext()) {
current = iterator.Current;
}
return current;
}
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
EndOfStream();
iterator.Dispose();
iterator = null;
current = null;
}
base.Dispose(disposing);
}
public StreamEnumerator(IEnumerable source, bool closeStreams)
{
if (source == null) throw new ArgumentNullException("source");
iterator = source.GetEnumerator();
this.closeStreams = closeStreams;
}
public override bool CanRead { get { return true; } }
public override bool CanWrite { get { return false; } }
public override void Write(byte[] buffer, int offset, int count)
{
throw new NotSupportedException();
}
public override void WriteByte(byte value)
{
throw new NotSupportedException();
}
public override bool CanSeek { get { return false; } }
public override bool CanTimeout { get { return false; } }
public override void SetLength(long value)
{
throw new NotSupportedException();
}
public override long Seek(long offset, SeekOrigin origin)
{
throw new NotSupportedException();
}
public override void Flush()
{ /* nothing to do */ }
public override long Length
{
get { throw new NotSupportedException(); }
}
public override long Position
{
get { return position; }
set { if (value != this.position) throw new NotSupportedException(); }
}
public override int Read(byte[] buffer, int offset, int count)
{
int result = 0;
while (count > 0)
{
Stream stream = Current;
if (stream == null) break;
int thisCount = stream.Read(buffer, offset, count);
result += thisCount;
count -= thisCount;
offset += thisCount;
if (thisCount == 0) EndOfStream();
}
position += result;
return result;
}
}