How do I concatenate two System.Io.Stream instances into one?

前端 未结 5 732
耶瑟儿~
耶瑟儿~ 2020-11-29 04:44

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

5条回答
  •  囚心锁ツ
    2020-11-29 05:12

    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;
        }
    }
    

提交回复
热议问题