C#重用GZipStream进行多次解压

C# reuse GZipStream for more than one decompressions

我需要单独压缩和解压缩数百万个字符串。第一个循环有效。第二个没有。基本上我不知道如何使用流。如何使第二种方法(重用流的方法)起作用?

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication1 {
    class Program {
        static void Main(string[] args) {
            string s = "Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah ";
            for (int i=0; i<10000; ++i) {
                var aCompressed = Zip(Encoding.ASCII.GetBytes(s));
                var aDecompressed = UnZip(aCompressed, 0, aCompressed.Length);
                string sDbg = System.Text.Encoding.ASCII.GetString(aDecompressed);
                Debug.Assert(sDbg == s);
            }
            // This loop is an utter failure.
            var UnZipper = new CUnZip(); // attempt to setup all the unzip framework once
            for (int i = 0; i < 10000; ++i) {
                var aCompressed = Zip(Encoding.ASCII.GetBytes(s));
                var aDecompressed = UnZipper.UnZip(aCompressed, 0, aCompressed.Length);
                string sDbg = System.Text.Encoding.ASCII.GetString(aDecompressed);
                Debug.Assert(sDbg == s);
            }
        }
        static byte[] Zip(byte[] aIn) {
            using (var outStream = new MemoryStream()) {
                using (var tinyStream = new GZipStream(outStream, CompressionMode.Compress))
                using (var mStream = new MemoryStream(aIn))
                    mStream.CopyTo(tinyStream);
                return outStream.ToArray();
            }
        }
        static byte[] UnZip(byte[] aIn, int i0, int cb) {
            using (var inStream = new MemoryStream(aIn, i0, cb))
            using (var bigStream = new GZipStream(inStream, CompressionMode.Decompress))
            using (var bigStreamOut = new MemoryStream()) {
                bigStream.CopyTo(bigStreamOut);
                return bigStreamOut.ToArray();
            }
        }
        // this class is an utter failure
        class CUnZip {
            GZipStream bigStream;
            MemoryStream inStream, bigStreamOut;
            BinaryWriter argh;
            public CUnZip() {
                inStream = new MemoryStream();
                argh = new BinaryWriter(inStream);
                bigStream = new GZipStream(inStream, CompressionMode.Decompress);
                bigStreamOut = new MemoryStream();
            }
            public byte[] UnZip(byte[] aIn, int i0, int cb) {
                argh.Write(aIn, i0, cb);
                argh.Flush();
                bigStream.CopyTo(bigStreamOut);
                return bigStreamOut.ToArray();
            }
        }
    }
}

已测试您的以下代码将解决问题:

inStream.Position = 0;

class CUnZip-UnZip Method

中设置postargh.Flush()

详情:

当您在 CUnZip class 中重复使用 MemoryStream 时,它的位置设置为写入的最后一个字节并执行任何需要读取它的操作,您需要将 position 重置为开头 (0),否则它没有任何内容可读,因此即使 stream 包含无法读取的数据,因为它指向 [= 的末尾17=]