Сжатый контент в байтовом массиве до несжатого в строке

Как мы можем создать простую функцию, чтобы брать сжатый контент из массива байтов (сжатый методом Deflate, закодированный в ANSI) и выражать его в виде строки?

Я иду с этим:

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 "";
        }
    }

Я могу видеть прочитанные сжатые данные inputMemoryStream, если я хочу, но uncompressedContent, предоставленный StreamReader.ReadToEnd(), всегда возвращает пустую строку. Согласно MSDN ( https://msdn.microsoft.com/en-us/library/system.io.streamreader.readtoend(v=vs.110).aspx), это должно произойти, когда он прочитан и позиция уже в конце "потока" (я путаюсь с каким потоком), но StreamReader не имеет позиции, и я не могу изменить позицию DeflateStream, потому что это поток без позиции и длины, и т.п.

Установка позиции compressStream в 0 до того, как копировать приводит к длине блока, не совпадает с ошибкой его дополнения в любом случае.

РЕДАКТИРОВАТЬ:

Когда я использую решение 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());
    }
}

Это приводит к дилемме, которая у меня всегда была: либо мне это нравится, и функция DeflateStream.CopyTo возвращает ошибку "Длина блока не соответствует его дополнению"; или я потребляю тогда два первых байта, и это на самом деле не приносит никакой ошибки, но все равно ничего не копирует, а затем возвращает пустую строку...

Если я пытаюсь распаковать FileStream файла вместо его массива байтов, происходит та же самая ситуация. Я использую функцию распаковки, приведенную в 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 "";
    }

Та же самая ошибка "Длина блока не совпадает с его дополнением"...

Одна вещь заключается в том, что расширение моего файла - это не ".zip", добавляемый в конец файла, а другое расширение (.23U в этом случае). Когда я создаю новый файл с таким же расширением (.23U вместо расширения в этом случае), возникает та же проблема.

1 ответ

Ваш метод распаковки должен быть примерно таким, как показано ниже. Не уверен, откуда у вас идея использовать первые 2 байта, прежде чем вы сможете прочитать поток.

    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());
        }
    }
Другие вопросы по тегам