Greg Young [MVP]

Sponsors

The Lounge

News

Advertisement

Images in this post missing? We recently lost them in a site migration. We're working to restore these as you read this. Should you need an image in an emergency, please contact us at imagehelp@codebetter.com
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             OneToTenIdea = 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 }


Posted Thu, Mar 27 2008 12:41 PM by Greg

[Advertisement]

Comments

Shawn Wildermuth wrote re: IteratorStream
on Thu, Mar 27 2008 2:09 PM
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?
Greg wrote re: IteratorStream
on Thu, Mar 27 2008 2:29 PM

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

codebetter.com/.../entry175969.aspx

friend wrote re: IteratorStream
on Thu, Mar 27 2008 4:45 PM

plz post your code snippets at www.codekeep.net

Greg wrote re: IteratorStream
on Thu, Mar 27 2008 5:21 PM
Dew Drop - March 28, 2008 | Alvin Ashcraft's Morning Dew wrote Dew Drop - March 28, 2008 | Alvin Ashcraft's Morning Dew
on Fri, Mar 28 2008 9:38 AM

Pingback from  Dew Drop - March 28, 2008 | Alvin Ashcraft's Morning Dew

Jason Haley wrote Interesting Finds: March 28, 2008
on Fri, Mar 28 2008 10:13 AM
Greg wrote re: IteratorStream
on Sat, Mar 29 2008 3:57 PM

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

remove the z's

Charlie Calvert's Community Blog wrote Community Convergence XLII
on Mon, Mar 31 2008 12:56 AM

Welcome to the forty-second issue of Community Convergence. The last few weeks have been a busy time

Add a Comment

(required)  
(optional)
(required)  
Remember Me?