错误:GZip头中的魔数不正确。

4
我有两种方法,一种是将图像转换为Base64字符串以便在XML标签中存储它,另一种是将Base64字符串转换回图像。我能够将图像转换为字符串并将其存储在XML中,但是当我尝试将字符串转换回图像时,出现以下错误:“GZip头中的魔数不正确。请确保您正在传递一个GZip流。” 有什么解决方法吗?
public static string ConvertToBase64String(Image Image, ImageFormat Format)
{
    MemoryStream stream = new MemoryStream();
    Image.Save(stream, Format);

    byte[] imageBytes = stream.ToArray();

    MemoryStream memStream = new MemoryStream();
    GZipStream zipStream = new GZipStream(memStream, CompressionMode.Compress);
    zipStream.Write(imageBytes, 0, imageBytes.Length);

    string imageString = Convert.ToBase64String(imageBytes);

    stream.Close();
    memStream.Close();

    return imageString;
}

public static Image Base64StringToImage(string ImageArray)
{
    byte[] base64String = Convert.FromBase64String(ImageArray);

    MemoryStream memStream = new MemoryStream(base64String);
    GZipStream zipStream = new GZipStream(memStream, CompressionMode.Decompress);
    zipStream.Read(base64String, 0, base64String.Length);

    ImageConverter ic = new ImageConverter();
    Image image = (Image)ic.ConvertFrom(base64String);

    memStream.Close();

    return image;
}
1个回答

6
我看到代码中有几个错误。
导致错误信息的问题是,您没有将转换为 base64 字符串的内容(memStream.ToArray())压缩,而是写入 zip 流的数据(imageBytes)。当您尝试解压未经过压缩的数据时,会出现错误消息。
另一个主要问题是,您仅从 zip 流中读取了部分数据,因为您使用了压缩数据的大小作为从 zip 流中读取多少数据的大小。
此外,您忽略了 Read 方法的结果。它返回实际放置在数组中的字节数,可能小于请求的字节数。由于 Read 方法不必返回所有可用数据,因此必须循环直到实际从流中获取了所有数据。当没有更多数据可读取时,Read 方法将返回零。
另一个问题是,您正在向用作内存流后端的数组中写入数据,而您正在从中读取。由于未压缩的数据通常比压缩的数据大,因此您将比读取速度更快地覆盖数据。但是,由于未压缩的数据无法适合数组,因此无法将其用于该目的。

我怎么知道解压缩后的数据大小呢?我需要创建一个我认为足够进行解压缩的随机字节大小吗?我处理的是图片,所以这个数字可能会相当大。 - Icono123
1
@Icono123:检查一下是否可以询问GZipStream大小,否则唯一的选择是将原始大小与数据一起存储。如果无法这样做,您必须在读取流时分配更多数据。您可以使用MemoryStream来为您完成此操作。 - Guffa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接