将两个单向流组合成双向流

时间:2011-12-05 16:41:48

标签: c# sockets compression

特别是我使用Ionic.Zlib.ZlibStreamSystem.Net.Sockets.NetworkStream进行Zlib压缩。

问题是,ZlibStream是一个单向流;您可以Read()Write()但不能同时使用Read()Write()。您需要两个单独的流,一个用于发送,一个用于接收(一个压缩,另一个解压缩)。哪个工作正常,直到您需要将其传递给期望单个双向流(new System.Net.Security.SslStream(Stream base)Stream功能)的函数。例如,{{1}}。

我意识到我可以写一个{{1}}类,它接受写入流和读取流,并在覆盖中调用正确的流。但我希望这已经存在于某个框架中,或者已经有了一个实现。

2 个答案:

答案 0 :(得分:2)

我很确定没有课程会为你做这件事。但是,你需要编写的包装类很简单,不应该花很长时间。

您可能会继承 Stream ,但如果您分析您的需求和其他可用的流类型,您可能会发现继承自更具体的类会帮助您。

修改:由于Lucas B的评论。

请注意, Stream 对象的正常使用要求它们实际上从 Stream 继承。否则,您无法将其作为参数传递给期望流的大量函数。

答案 1 :(得分:2)

如果框架中尚不存在,那就够了。

    public class StreamRWJoin : Stream {
        public Stream WriteStream { get; set; }
        public Stream ReadStream { get; set; }
        private bool leaveOpen;

        public StreamRWJoin(Stream readfrom, Stream writeto, bool leaveOpen = false) {
            WriteStream = writeto; ReadStream = readfrom;
            this.leaveOpen = leaveOpen;
        }

        public override bool CanRead {
            get { return ReadStream.CanRead; }
        }

        public override bool CanSeek {
            get { return false; }
        }

        public override bool CanWrite {
            get { return WriteStream.CanWrite; }
        }

        public override void Flush() {
            WriteStream.Flush();
        }

        public override long Length {
            get { throw new NotImplementedException(); }
        }

        public override long Position {
            get {
                throw new NotImplementedException();
            }
            set {
                throw new NotImplementedException();
            }
        }

        public override int Read(byte[] buffer, int offset, int count) {
            return ReadStream.Read(buffer, offset, count);
        }

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

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

        public override void Write(byte[] buffer, int offset, int count) {
            WriteStream.Write(buffer, offset, count);
        }

        public override void Close() {
            if (!leaveOpen)
                try {
                    WriteStream.Close();
                } finally {
                    ReadStream.Close();
                }
        }

        public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state) {
            return ReadStream.BeginRead(buffer, offset, count, callback, state);
        }
        public override int EndRead(IAsyncResult asyncResult) {
            return ReadStream.EndRead(asyncResult);
        }

        public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state) {
            return WriteStream.BeginWrite(buffer, offset, count, callback, state);
        }
        public override void EndWrite(IAsyncResult asyncResult) {
            WriteStream.EndWrite(asyncResult);
        }

        public override int ReadByte() {
            return ReadStream.ReadByte();
        }
        public override void WriteByte(byte value) {
            ReadStream.WriteByte(value);
        }

        public override int ReadTimeout {
            get {
                return ReadStream.ReadTimeout;
            }
            set {
                ReadStream.ReadTimeout = value;
            }
        }

        public override int WriteTimeout {
            get {
                return WriteStream.WriteTimeout;
            }
            set {
                WriteStream.WriteTimeout = value;
            }
        }

        public override bool CanTimeout {
            get {
                return ReadStream.CanTimeout || WriteStream.CanTimeout;
            }
        }

        public override int GetHashCode() {
            return ReadStream.GetHashCode() ^ WriteStream.GetHashCode();
        }

        protected override void Dispose(bool disposing) {
            if (disposing && !leaveOpen) {
                try {
                    ReadStream.Dispose();
                } finally {
                    WriteStream.Dispose();
                }
            }
        }

        public override string ToString() {
            return "Read: " + ReadStream.ToString() + ", Write: " + WriteStream.ToString();
        }
    }