C# 将两条单向流合并为一条双向流

C# 将两条单向流合并为一条双向流,c#,sockets,compression,C#,Sockets,Compression,特别是,我使用Ionic.Zlib.ZlibStream在System.Net.Sockets.NetworkStream上进行Zlib压缩 问题是,ZlibStream是单向流;您可以Read()或Write(),但不能两者兼而有之。您需要两个独立的流,一个用于发送,一个用于接收(一个压缩,另一个解压缩)。在您需要将其传递给需要单个双向流的函数(既有Read()功能,也有Write()功能)之前,它可以正常工作。例如,newsystem.Net.Security.SslStream(流基) 我

特别是,我使用
Ionic.Zlib.ZlibStream
System.Net.Sockets.NetworkStream
上进行Zlib压缩

问题是,
ZlibStream
是单向流;您可以
Read()
Write()
,但不能两者兼而有之。您需要两个独立的流,一个用于发送,一个用于接收(一个压缩,另一个解压缩)。在您需要将其传递给需要单个双向流的函数(既有
Read()
功能,也有
Write()
功能)之前,它可以正常工作。例如,
newsystem.Net.Security.SslStream(流基)


我意识到我可以编写一个
类,它接受一个写流和一个读流,并在重写中调用正确的流。但是我希望这已经存在于框架中的某个地方,或者已经有了一个实现。

我很确定没有类可以为您这样做。但是,您需要编写的包装器类很简单,根本不需要花很长时间

您可能会从流继承,但如果您分析您的需求和其他可用的流类型,您可能会发现从更具体的类继承将帮助您解决问题

编辑:由于Lucas B的评论


请记住,流对象的正常使用要求它们实际从流继承。否则,您不能将其作为参数传递给大量需要流的函数。

如果框架中还没有流,那么就很容易了

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

但是你应该在加密之前压缩,不是吗?这个问题不应该出现。@Henk,这只是一个例子。封装这一个的实际流是一个专有的XMPPStream,要给出一个有意义的例子肯定会更加困难?如果我错误地认为有一个类可以这样做,为什么没有一个答案告诉我们它是什么?@NickWhaley:我知道。:)你能告诉我谁投了反对票吗P