GZIP/DEFLATE压缩适用于.NETCORE 2.0,但对于.NET 4.6.2



我已经编写了一些代码,用于用GZIP或DEFLATE压缩和解压缩数据(均为Inside system.com.com-pression(,并且在一个.netcore项目中对其进行了测试,该项目正常工作,并且所有工作正常测试用例通过。因此,我在.NET 4.6.2项目中回收了相同的代码,尽管MSDN文档说它兼容,但我遇到问题以使其正常工作。在这里,您是代码的一部分,我对

有任何问题
public virtual byte[] Encode<TObject>(TObject objectToEncode) where TObject : class, new()
    {
        if (objectToEncode == null) throw new ArgumentNullException(nameof(objectToEncode));
        byte[] jsonResult = null;
        using (var ms = new MemoryStream())
        {
            //Generazione del Json
            using (var textWriter = new StreamWriter(ms, System.Text.Encoding.UTF8))
            {
                using (var jsonWriter = new JsonTextWriter(textWriter))
                {
                    JsonSerializer serializer = new JsonSerializer();
                    serializer.Serialize(jsonWriter, objectToEncode, objectToEncode.GetType());
                    jsonWriter.Flush();
                    textWriter.Flush();
                    ms.Flush();
                    //Compressione Json   
                    jsonResult = ms.ToArray();
                }
            }
        }
        using (var msResult = new MemoryStream())
        {
            using (var encodingStream = GenerateEncodingStream(msResult))
            {
                encodingStream.Write(jsonResult, 0, Convert.ToInt32(jsonResult.Length));
                encodingStream.Flush();
                msResult.Position = 0;
                return msResult.ToArray();
            }
        }
    }

生成engeCondingStream只需调用DeflateStream或gzipstream的构造函数,具体取决于您选择的。

问题:如果我使用Deflate,则MSRESULT.LENGHT为0个单元格,而如果我使用GZIP长度msresult.length.length是同一数据集的10个单元格(.netcore Project中的211个(。

大量使用flush((是为了确保每个流都在应有的位置完全冲洗。.NET 4.6.2有问题,还是我的代码错误?感谢您的帮助!

编辑:同样的问题,但是随着解压缩和挑选化的情况:如果我解压缩,然后在关闭所有流后进行了挑选,则我的性能的10%比下面列出的版本使用了无效的流。下面的代码在解压缩的同时未能进行反序列化。我没有想法,因为具有10%效果的版本是不可接受的...

public virtual async Task<object> DecodeAsync(byte[] encodedObject, Type decodedObjectType, CancellationToken cancellationToken)
    {           
        cancellationToken.ThrowIfCancellationRequested();
        if (encodedObject == null) throw new ArgumentNullException(nameof(encodedObject));
        if (encodedObject.Length == 0) throw new ArgumentException(nameof(encodedObject));
        using (var compressedStream = new MemoryStream(encodedObject))
        {
            using (var csStream = GenerateDecodingStream(compressedStream))
            {
                using (var decompressedStream = new MemoryStream())
                {
                    using (StreamReader sr = new StreamReader(decompressedStream, System.Text.Encoding.UTF8))
                    {
                        using (var reader = new JsonTextReader(sr))
                        {
                            JsonSerializer serializer = new JsonSerializer();
                            return serializer.Deserialize(reader, decodedObjectType);
                        }
                    }
                }
            }
        }
    }

DeflateStream的参考源中,Flush() 不做任何事情

在反射器中查看,常规.NET框架Flush()也是如此。因此,基本上,Flush()不想冲洗 - 大概是为了最大程度地提高压缩效率。相反,只有在数据大小足够大或处置

时才会发生冲洗。

相比之下,在.NET核心源中,Flush() 实际上是冲洗

so:将.ToArray()的调用移至您已关闭所有包装MemoryStream

so:

using (var ms = new MemoryStream())
{
    //Generazione del Json
    using (var textWriter = new StreamWriter(ms, System.Text.Encoding.UTF8))
    {
        using (var jsonWriter = new JsonTextWriter(textWriter))
        {
            JsonSerializer serializer = new JsonSerializer();
            serializer.Serialize(jsonWriter, objectToEncode, objectToEncode.GetType());                    
        }
    }
    jsonResult = ms.ToArray();
}
using (var msResult = new MemoryStream())
{
    using (var encodingStream = GenerateEncodingStream(msResult))
    {
        encodingStream.Write(jsonResult, 0, Convert.ToInt32(jsonResult.Length));                
    }
    return msResult.ToArray();
}

最新更新