IteratorStream

I had to write this quick little adapter the other day for something and figured it might be useful for people …

 

In general you are better off making the code that is using a stream not use a stream but to use an IEnumerable<byte []> since using stream you are required to copy … Buy for very large buffers this is far more efficient than copying into a MemoryStream.

 
 

 

   10 public class IteratorStream : Stream

   11 {

   12     private readonly IEnumerator<byte[]> m_Chunks;

   13     private ArraySegment<byte> m_CurrentChunk;

   14 

   15     public IteratorStream(IEnumerable<byte[]> _Chunks)

   16     {

   17         if (_Chunks == null) throw new ArgumentNullException();

   18         m_Chunks = _Chunks.GetEnumerator();

   19     }

   20 

   21     public override bool CanRead {

   22         get { return true; }

   23     }

   24 

   25     public override bool CanSeek

   26     {

   27         get { return false; }

   28     }

   29 

   30     public override bool CanWrite {

   31         get { return false; }

   32     }

   33     public override long Length { get { return -1; } }

   34 

   35     public override long Position

   36     {

   37         get { throw new NotImplementedException(); }

   38         set{ throw new NotImplementedException();}

   39     }

   40 

   41     private bool ReadNextChunk()

   42     {

   43         bool HasMore = m_Chunks.MoveNext();

   44         if (HasMore)

   45         {

   46             m_CurrentChunk = new ArraySegment<byte>(m_Chunks.Current);

   47         }

   48         return HasMore;

   49     }

   50 

   51     public override int Read(byte[] buffer, int offset, int count) {

   52         if (buffer == null) throw new ArgumentNullException(“buffer”);

   53         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”);

   54         if (count < 0) throw new ArgumentException(“count must be greater than or equal to 0″);

   55         if (offset + count > buffer.Length) throw new ArgumentException(“offset + count must be less than the buffer size”);

   56 

   57         int LeftToRead = count;

   58         int CurrentLocation = offset;

   59         if (m_CurrentChunk.Count == 0)

   60         {

   61             if (!ReadNextChunk())

   62             {

   63                 return 0;

   64             }

   65         }

   66         while (LeftToRead > 0 && m_CurrentChunk.Count != 0)

   67         {

   68             int toRead = (LeftToRead > m_CurrentChunk.Count) ? m_CurrentChunk.Count : LeftToRead;

   69             Buffer.BlockCopy(m_CurrentChunk.Array, m_CurrentChunk.Offset, buffer, CurrentLocation, toRead);

   70             LeftToRead -= toRead;

   71             CurrentLocation += toRead;

   72             m_CurrentChunk = new ArraySegment<byte>(m_CurrentChunk.Array, m_CurrentChunk.Offset + toRead, m_CurrentChunk.Count – toRead);

   73             if (m_CurrentChunk.Count == 0)

   74             {

   75                 ReadNextChunk();

   76             }

   77         }

   78         return count – LeftToRead;

   79     }

   80 

   81     protected override void Dispose(bool disposing)

   82     {

   83         base.Dispose(disposing);

   84         if (disposing && m_Chunks != null)

   85         {

   86             m_Chunks.Dispose();

   87         }

   88 

   89     }

   90 

   91     public override long Seek(long offset, SeekOrigin loc) { throw new NotImplementedException(); }

   92     public override void SetLength(long value) { throw new NotImplementedException(); }

   93     public override void Write(byte[] buffer, int offset, int count) { throw new NotImplementedException(); }

   94     public override void Flush() { throw new NotImplementedException(); }

   95     public override void WriteByte(byte value) { throw new NotImplementedException(); }

   96 }

   97 

   98 

   99 class Program

  100 {

  101     static IEnumerable<byte[]> GetBytes()

  102     {

  103         byte [] OneToTen = new byte[10];

  104         for(byte i=0;i<10;i++)

  105             OneToTen[i] = i;

  106         for(int j = 0;j <10;j++) {

  107             yield return OneToTen;

  108         }

  109     }

  110 

  111     static void Main(string[] args)

  112     {

  113         IteratorStream stream;

  114         using (stream = new IteratorStream(GetBytes()))

  115         {

  116             int read = stream.ReadByte();

  117 

  118             //read 1 byte at a time

  119             while (read != -1)

  120             {

  121                 Console.WriteLine(read.ToString());

  122                 read = stream.ReadByte();

  123             }

  124         }

  125 

  126         //read 100 bytes

  127         using (stream = new IteratorStream(GetBytes()))

  128         {

  129             byte[] buffer = new byte[100];

  130             int read = stream.Read(buffer, 0, 100);

  131             Console.WriteLine(read);

  132         }

  133 

  134     }

  135 }

This entry was posted in Uncategorized. Bookmark the permalink. Follow any comments here with the RSS feed for this post.

46 Responses to IteratorStream

  1. Pharmg795 says:

    Very nice site! [url=http://oieypxa.com/oryrqqr/2.html]cheap cialis[/url]

  2. Greg says:

    To the person asking for email … you can reach me at grzegoryzyozung1 at gmail

    remove the z’s

  3. friend says:

    plz post your code snippets at http://www.codekeep.net

  4. Greg Young says:

    Here is the URL to the code … just put into a quick console application

    http://codebetter.com/files/folders/codebetter_downloads/entry175969.aspx

  5. This is cool but the code is a mess because of the host being smart about smiley’s and such. Do you think you could provide it as a downloadable .cs?

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>