using System; using System.Collections.Generic; using System.Text; using System.IO; namespace ConsoleApplication5 { public class IteratorStream : Stream { private readonly IEnumerator m_Chunks; private ArraySegment m_CurrentChunk; public IteratorStream(IEnumerable _Chunks) { if (_Chunks == null) throw new ArgumentNullException(); m_Chunks = _Chunks.GetEnumerator(); } public override bool CanRead { get { return true; } } public override bool CanSeek { get { return false; } } public override bool CanWrite { get { return false; } } public override long Length { get { return -1; } } public override long Position { get { throw new NotImplementedException(); } set{ throw new NotImplementedException();} } private bool ReadNextChunk() { bool HasMore = m_Chunks.MoveNext(); if (HasMore) { m_CurrentChunk = new ArraySegment(m_Chunks.Current); } return HasMore; } public override int Read(byte[] buffer, int offset, int count) { if (buffer == null) throw new ArgumentNullException("buffer"); if (offset < 0 || offset >= buffer.Length) throw new ArgumentException("offset must be greater than or equal to 0 and less than the size of the buffer"); if (count < 0) throw new ArgumentException("count must be greater than or equal to 0"); if (offset + count > buffer.Length) throw new ArgumentException("offset + count must be less than the buffer size"); int LeftToRead = count; int CurrentLocation = offset; if (m_CurrentChunk.Count == 0) { if (!ReadNextChunk()) { return 0; } } while (LeftToRead > 0 && m_CurrentChunk.Count != 0) { int toRead = (LeftToRead > m_CurrentChunk.Count) ? m_CurrentChunk.Count : LeftToRead; Buffer.BlockCopy(m_CurrentChunk.Array, m_CurrentChunk.Offset, buffer, CurrentLocation, toRead); LeftToRead -= toRead; CurrentLocation += toRead; m_CurrentChunk = new ArraySegment(m_CurrentChunk.Array, m_CurrentChunk.Offset + toRead, m_CurrentChunk.Count - toRead); if (m_CurrentChunk.Count == 0) { ReadNextChunk(); } } return count - LeftToRead; } protected override void Dispose(bool disposing) { base.Dispose(disposing); if (disposing && m_Chunks != null) { m_Chunks.Dispose(); } } public override long Seek(long offset, SeekOrigin loc) { 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(); } public override void Flush() { throw new NotImplementedException(); } public override void WriteByte(byte value) { throw new NotImplementedException(); } } class Program { static IEnumerable GetBytes() { byte [] OneToTen = new byte[10]; for(byte i=0;i<10;i++) OneToTen[i] = i; for(int j = 0;j <10;j++) { yield return OneToTen; } } static void Main(string[] args) { IteratorStream stream; using (stream = new IteratorStream(GetBytes())) { int read = stream.ReadByte(); //read 1 byte at a time while (read != -1) { Console.WriteLine(read.ToString()); read = stream.ReadByte(); } } //read 100 bytes using (stream = new IteratorStream(GetBytes())) { byte[] buffer = new byte[100]; int read = stream.Read(buffer, 0, 100); Console.WriteLine(read); } } } }