Feedback

C# - Stream, der mit foreach() durchlaufen werden kann

Veröffentlicht von am 31.10.2009
(2 Bewertungen)
Dies ist ein Stream-Wrapper mit dem man einen Basisstream mit einer foreach()-Schleife durchlaufen kann. Beispiel:


System.IO.Stream datei = System.IO.File.OpenRead(@"D:\datei_tm.png");

// Stream erstellen mit einer Puffergrösse von 10240 Bytes, den Stream beim "Disposen" ebenfalls schliessen
using (stream = new EnumerableStream(datei, 10240, true))
{
foreach (byte[] daten in stream)
{
Console.WriteLine(daten.Length);
}
}
GFU-Schulungen  [Anzeige]

ASP.NET Core und Angular Komplett für .NET-Entwickler

Sie  lernen in drei (3) Tagen wie man mit  ASP.NET Core und den Technologien  MVC, Entity Framework, WebAPI und  Razor professionelle sowie moderne  Web-Anwendungsarchitekturen aufbaut.  Die Schulung ist der perfekte  Einstieg um insbesondere datengetriebene  und präsentationsorientierte  Applikationen auf Basis der robusten und  skalierbaren ASP.NET Core  Plattform zu erstellen. Nach der Veranstaltung kennen Sie die Konzepte von Angular und können Angular in neue und bestehende ASP.NET-Anwendungen einsetzen.

C# 2017/2015/2013 Grundlagen

Nach Abschluss des Kurses sind Ihnen die Datentypen und Klassenbibliotheken von C# bekannt. Außerdem sind Sie in der Lage, mit Variablen umzugehen und deren Typen zu konvertieren. Sie definieren Namespaces und setzen diese ein, Sie erstellen eigene Klassen  und bauen Trouble Shooting ein.

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;

namespace MarcelJKloubert.IO
{
    /// <summary>
    /// Ein Stream, der durchlaufen werden kann
    /// </summary>
    public sealed class EnumerableStream : Stream, IEnumerable<byte[]>
    {
        #region CLASS: StreamEnumerator
        private class StreamEnumerator : IEnumerator<byte[]>
        {
            #region Felder
            private byte[] _current = null;
            private StreamEnumerable _parent = null;
            #endregion


            #region Konstruktoren
            public StreamEnumerator(StreamEnumerable parent)
            {
                if (null == parent)
                {
                    throw new ArgumentNullException("parent");
                }

                this._parent = parent;
            }
            #endregion


            #region Eigenschaften
            /// <summary>
            /// 
            /// </summary>
            /// <see cref="System.Collections.Generic.IEnumerator&lt;T&gt;.Current"/>
            public byte[] Current
            {
	            get { return this._current; }
            }

            /// <summary>
            /// 
            /// </summary>
            /// <see cref="System.Collections.IEnumerator.Current"/>
            object IEnumerator.Current
            {
	            get { return this.Current; }
            }

            /// <summary>
            /// Gibt die Vaterinstanz zurück
            /// </summary>
            public StreamEnumerable Parent
            {
                get { return this._parent; }
            }
            #endregion

            #region Methoden
            /// <summary>
            /// 
            /// </summary>
            /// <see cref="System.IDisposable.Dispose"/>
            public void Dispose()
            { }

            /// <summary>
            /// 
            /// </summary>
            /// <see cref="System.Collections.Generic.IEnumerator&lt;T&gt;.MoveNext"/>
            public bool MoveNext()
            {
                byte[] buffer = new byte[this.Parent.BufferSize];

                int iBytesRead = this.Parent.Read(buffer, 0, buffer.Length);
                if (iBytesRead > 0)
                {
                    byte[] data = new byte[iBytesRead];
                    Array.Copy(buffer, data, iBytesRead);

                    this._current = data;
                }

                return iBytesRead > 0;
            }

            /// <summary>
            /// 
            /// </summary>
            /// <see cref="System.Collections.Generic.IEnumerator&lt;T&gt;.Reset"/>
            public void Reset()
            {
                if (this.Parent.CanSeek)
                {
                    this.Parent.Position = 0;
                }

                this._current = null;
            }
            #endregion
        }
        #endregion


        #region Felder
        private Stream _baseStream   = null;
        private int _bufferSize      = 0;
        private bool _closeOnDispose = false;
        #endregion


        #region Konstruktoren
        /// <summary>
        /// 
        /// </summary>
        /// <param name="baseStream">Basisstream</param>
        public StreamEnumerable(Stream baseStream) : this(baseStream, 4096)
        { }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="baseStream">Basisstream</param>
        public StreamEnumerable(Stream baseStream, int bufferSize) : this(baseStream, bufferSize, false)
        { }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="baseStream">Basisstream</param>
        /// <param name="closeAfterDispose">Speicher von Basisstream ebenfalls freigeben bei einem Dispose() (true) oder nicht (false)</param>
        public StreamEnumerable(Stream baseStream, bool closeOnDispose) : this(baseStream, 4096, closeOnDispose)
        { }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="baseStream">Basisstream</param>
        /// <param name="bufferSize">Puffergrösse</param>
        /// <param name="closeAfterDispose">Speicher von Basisstream ebenfalls freigeben bei einem Dispose() (true) oder nicht (false)</param>
        public StreamEnumerable(Stream baseStream, int bufferSize, bool closeOnDispose)
        {
            if (null == baseStream)
            {
                throw new ArgumentNullException("baseStream");
            }

            if (bufferSize < 1)
            {
                throw new ArgumentOutOfRangeException("bufferSize");
            }

            this._baseStream = baseStream;
            this._bufferSize = bufferSize;
            this._closeOnDispose = closeOnDispose;
        }
        #endregion

        #region Eigenschaften
        /// <summary>
        /// Gibt den Basisstream zurück
        /// </summary>
        public Stream BaseStream
        {
            get { return this._baseStream; }
        }

        /// <summary>
        /// Gibt die Puffergrösse zurück
        /// </summary>
        public int BufferSize
        {
            get { return this._bufferSize; }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <see cref="System.IO.Stream.CanRead"/>
        public override bool CanRead
        {
            get { return this.BaseStream.CanRead; }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <see cref="System.IO.Stream.CanSeek"/>
        public override bool CanSeek
        {
            get { return this.BaseStream.CanSeek; }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <see cref="System.IO.Stream.CanWrite"/>
        public override bool CanWrite
        {
            get { return this.BaseStream.CanWrite; }
        }

        /// <summary>
        /// Gibt zurück, ob der Speicher des Basisstream ebenfalls bei einem Dispose() freigegeben wird (true) oder nicht (false)
        /// </summary>
        public bool CloseOnDispose
        {
            get { return this._closeOnDispose; }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <see cref="System.IO.Stream.Length"/>
        public override long Length
        {
            get { return this.BaseStream.Length; }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <see cref="System.IO.Stream.Position"/>
        public override long Position
        {
            get { return this.BaseStream.Position; }
            
            set { this.BaseStream.Position = value; }
        }
        #endregion

        #region Methoden
        /// <summary>
        /// 
        /// </summary>
        /// <see cref="System.IO.Stream.Dispose"/>
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (this.CloseOnDispose)
                {
                    this.BaseStream.Dispose();
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <see cref="System.IO.Stream.Flush"/>
        public override void Flush()
        {
            this.BaseStream.Flush();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <see cref="System.Collections.Generic.IEnumerable&lt;T&gt;.GetEnumerator"/>
        public IEnumerator<byte[]> GetEnumerator()
        {
            return new StreamEnumerator(this);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <see cref="System.Collections.IEnumerable.GetEnumerator"/>
        IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return this.GetEnumerator();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <see cref="System.IO.Stream.Read"/>
        public override int Read(byte[] buffer, int offset, int count)
        {
            return this.BaseStream.Read(buffer, offset, count);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <see cref="System.IO.Stream.Seek"/>
        public override long Seek(long offset, SeekOrigin origin)
        {
            return this.BaseStream.Seek(offset, origin);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <see cref="System.IO.Stream.SetLength"/>
        public override void SetLength(long value)
        {
            this.BaseStream.SetLength(value);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <see cref="System.IO.Stream.Write"/>
        public override void Write(byte[] buffer, int offset, int count)
        {
            this.BaseStream.Write(buffer, offset, count);
        }
        #endregion
    }
}

4 Kommentare zum Snippet

Sperneder Patrick schrieb am 08.11.2009:
Sehr elegant ! Von mir dafür eine glatte 10.
Marcel Kloubert schrieb am 10.11.2009:
Besten Dank! :-)

Kleinen Schönheitsfehler hat der Code, hab ich grad gesehen: Die Konstruktoren sind falsch genamt. Die müssen "EnumerableStream" statt "StreamEnumerable" (so hies die Klasse vorher!). Ich kanns leider wieder nicht ändern ... wieder ein Serverfehler beim Versuch den Code zu ändern ... einer der Gründe warum ich lieber Webseiten in PHP programmiere ;-)
Marcel Kloubert schrieb am 10.11.2009:
selbes gilt im übrigen für den Paramater des Konstruktors von StreamEnumerator...
Marcel Kloubert schrieb am 10.11.2009:
und den rest in StreamEnumerator...
 

Logge dich ein, um hier zu kommentieren!