解压缩gzipstream时出错 - GZip标头中的幻数不正确

时间:2014-11-25 21:11:38

标签: c# .net

我正在使用C#System.IO类(框架4.0)来压缩从FileDialog文件系统中拉出的图像,然后作为varbinary(max)数据插入到SQL Server数据库中类型。我遇到的问题是当我从数据库中提取数据并尝试解压缩时,我会收到另一条消息的主题错误 - 请确保传入gzip流。

获取文件的代码:

    OpenFileDialog dlgOpen = new OpenFileDialog();

    if (dlgOpen.ShowDialog() == DialogResult.OK)
    {
        FileStream fs = File.OpenRead(dlgOpen.FileName);
        byte[] picbyte1 = new byte[fs.Length];
        byte[] picbyte = Compress(picbyte1);
        fs.Read(picbyte, 0, System.Convert.ToInt32(picbyte.Length));
        String ImageName = dlgOpen.FileName;
        //String bs64OfBytes = Convert.ToBase64String(picbyte);
        fs.Close();
        //additional code inserts into database
        ....

     }

压缩方法:

        private static byte[] Compress(byte[] data)
        {
            var output = new MemoryStream();
            using (var gzip = new GZipStream(output, CompressionMode.Compress, true))
            {
                gzip.Write(data, 0, data.Length);
                gzip.Close();
            }
            return output.ToArray();
        }

解压缩方法:

        private static byte[] Decompress(byte[] data)
        {
            var output = new MemoryStream();
            var input = new MemoryStream();
            input.Write(data, 0, data.Length);
            input.Position = 0; 

            using (var gzip = new GZipStream(input, CompressionMode.Decompress, true))
            {
                var buff = new byte[64];//also used 32
                var read = gzip.Read(buff, 0, buff.Length);//error occurs here

                while (read > 0)
                {
                    output.Write(buff, 0, read);
                    read = gzip.Read(buff, 0, buff.Length);
                }

                gzip.Close();
            }
            return output.ToArray();
        }

1 个答案:

答案 0 :(得分:1)

您需要插入一行并删除另一行:

FileStream fs = File.OpenRead(dlgOpen.FileName);
byte[] picbyte1 = new byte[fs.Length];
fs.Read(picbyte1, 0, (int)fs.Length); // <-- Add this one
byte[] picbyte = Compress(picbyte1);
// fs.Read(picbyte, 0, System.Convert.ToInt32(picbyte.Length)); // <-- And remove this one
// ...

您正在阅读代码中的图片,但有些内容的顺序错误:

// Original but incorrect sequence
FileStream fs = File.OpenRead(dlgOpen.FileName); // Open the file
byte[] picbyte1 = new byte[fs.Length]; // Assign the array
byte[] picbyte = Compress(picbyte1); // Compress the assigned array, but there is no contents...
fs.Read(picbyte, 0, System.Convert.ToInt32(picbyte.Length)); // You save the file to the already compressed bytes...

因此您保存了原始文件的第一部分,而不是压缩文件(但保存的字节数与压缩字节数相对应)。如果您将其发送到数据库并将其读回,则解压缩程序找不到它的幻数。

作为改进,您可以更改这些行:

FileStream fs = File.OpenRead(dlgOpen.FileName);
byte[] picbyte1 = new byte[fs.Length];
fs.Read(picbyte1, 0, (int)fs.Length); // line that I suggested to add

可能改为:

byte[] picbyte1 = File.ReadAllBytes(dlgOpen.FileName);