Compressed content in a byte array to uncompressed in a string

我怕爱的太早我们不能终老 提交于 2020-01-14 03:08:27

问题


How can we create a simple function to take the compressed content from an array of byte (compressed with Deflate method, ANSI encoded) and express it in a string?

I go with this one :

public string UnzipString3(byte[] byteArrayCompressedContent)
    {
        int compressedSize = byteArrayCompressedContent.Length;
        try
        {
            using (MemoryStream inputMemoryStream = new MemoryStream(byteArrayCompressedContent))
            {
                //I need to consume the first 2 bytes to be able read the stream
                //If I consume 0 or 4, I can't exploit it                        
                inputMemoryStream.Seek(2, SeekOrigin.Begin);
                using (DeflateStream deflateStream = new DeflateStream(inputMemoryStream, System.IO.Compression.CompressionMode.Decompress))
                {
                    //deflateStream.BaseStream.Position = 0;
                    using (StreamReader reader = new StreamReader(deflateStream, System.Text.Encoding.UTF8))
                    {
                        string uncompressedContent = reader.ReadToEnd();
                        reader.Close();
                        return uncompressedContent;
                    }
                }
            }
        }
        catch (Exception e)
        {
            return "";
        }
    }

I can see read the compressed data of inputMemoryStream if I want, but the uncompressedContent given by StreamReader.ReadToEnd() always return an empty string. According to MSDN (https://msdn.microsoft.com/en-us/library/system.io.streamreader.readtoend(v=vs.110).aspx), it is supposed to happen when it is read and the position is already at the end of the "Stream" (I get confused with which stream), but a StreamReader hasn't a position and I can't change the position of the DeflateStream, because it's a stream without a position and the length, etc.

Putting the compressStream position to 0 before to copy leads to a Block length does not match with its complement" error in anycase.

EDIT :

When I use the solution of RaTruong :

public static string UnzipString3(byte[] byteArrayCompressedContent)
{
    using (var outputStream = new MemoryStream())
    {
        using (var compressStream = new MemoryStream(byteArrayCompressedContent))
        {
            using (var deflateStream = new DeflateStream(compressStream, CompressionMode.Decompress))
            {
                deflateStream.CopyTo(outputStream);
            }
        }
        return Encoding.UTF8.GetString(outputStream.ToArray());
    }
}

It leads to the dilemma I always had : either I do like this and the DeflateStream.CopyTo function returns a "Block length does not match with its complement" error ; or I consume then two first bytes and it actually does not bring any error but still copy nothing and then returns an empty string...

If I try to decompress a FileStream of a File instead of its array of bytes, the same situation happens. I use the decompress function given in MSDN (https://msdn.microsoft.com/en-us/library/system.io.compression.deflatestream(v=vs.110).aspx) :

public string ExtractContent()
    {
        try
        {
            FileInfo fileInfo = new FileInfo("22CC0001.23U");
            // Get the stream of the source file.
            using (FileStream inFile = fileInfo.OpenRead())
            {
                // Get original file extension, for example
                // "doc" from report.doc.gz.
                string curFile = fileInfo.FullName;
                string origName = curFile.Remove(curFile.Length -
                        fileInfo.Extension.Length);
                //Create the decompressed file.
                using (FileStream outFile = File.Create(origName))
                {
                    using (DeflateStream decompressDeflateStream = new DeflateStream(inFile,
                            CompressionMode.Decompress))
                    {
                        // Copy the decompression stream 
                        // into the output file.
                        decompressDeflateStream.CopyTo(outFile);

                        Console.WriteLine("Decompressed: {0}", fileInfo.Name);
                    }
                }
            }
        }
        catch (Exception e)
        {
            return "errorelole";
        }
        return "";
    }

Same "Block length does not match with its complement" error...

One thing is that the extension of my file is not a ".zip" added at the end of a file, but another extension (.23U in that case). When I create a new file having the same extension (.23U instead of no extension in that case), the same problem occurs.


回答1:


Your unzip method should be something like below. Not sure where you got the idea of consuming the first 2 bytes before you can read the stream.

    public static string UnzipString3(byte[] byteArrayCompressedContent)
    {
        using (var outputStream = new MemoryStream())
        {
            using (var compressStream = new MemoryStream(byteArrayCompressedContent))
            {
                using (var deflateStream = new DeflateStream(compressStream, CompressionMode.Decompress))
                {
                    deflateStream.CopyTo(outputStream);
                }
            }

            return Encoding.UTF8.GetString(outputStream.ToArray());
        }
    }


来源:https://stackoverflow.com/questions/48771573/compressed-content-in-a-byte-array-to-uncompressed-in-a-string

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!