c# - 字节数组中的压缩内容以字符串形式解压缩

标签 c# filestream streamreader memorystream deflatestream

我们如何创建一个简单的函数来从字节数组中提取压缩内容(使用 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 的压缩数据,但是 StreamReader.ReadToEnd() 给出的未压缩内容总是返回一个空字符串。根据 MSDN(https://msdn.microsoft.com/en-us/library/system.io.streamreader.readtoend(v=vs.110).aspx),它应该在读取时发生并且位置已经在“流”的末尾(我对哪个流感到困惑),但是 StreamReader 没有位置,我不能改变 DeflateStream 的位置,因为它是一个没有位置和长度等的流。

在复制之前将 compressStream 位置设为 0 会导致 Block length does not match with its complement"错误在任何情况下。

编辑:

当我使用 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 函数返回一个“ block 长度与其补码不匹配”错误,要么我先消耗两个字节,它实际上不会带来任何错误,但仍然不复制任何内容然后返回一个空字符串...

如果我尝试解压缩文件的文件流而不是其字节数组,则会发生相同的情况。 我使用 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 "";
    }

同样的“ block 长度与其补码不匹配”错误...

一件事是我的文件的扩展名不是添加在文件末尾的“.zip”,而是另一个扩展名(在这种情况下为 .23U)。 当我创建一个具有相同扩展名(.23U 而不是在这种情况下没有扩展名)的新文件时,会出现同样的问题。

最佳答案

您的解压缩方法应该如下所示。不确定在读取流之前消耗前 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());
        }
    }

关于c# - 字节数组中的压缩内容以字符串形式解压缩,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48771573/

相关文章:

c# - StreamReader 无法正确读取扩展字符集 (UTF8)

c# - 如何在c#中读取网站内容?

c# - 如何从 C# 循环 USB 设备?

c# - MVC3 下拉列表为

c# - 如何在 C# 中的 REST API 中获取 PDF 文件

c# - 如何将 MemoryStream 转换为 FileStream?

c# - 奇怪的 Windows 7 桌面图标缓存

c# - 使用相同的 ConnectionString 打开两个 SQLConnections

c# - 从每 6 秒更新一次的二进制日志文件读取 12k 数据

C# - StreamReader.ReadLine 无法正常工作!