wpf 如何使用System.IO.Compression避免随机的无效数据异常

gcuhipw9  于 2023-01-14  发布在  其他
关注(0)|答案(1)|浏览(126)

我有一个包含三个jpg图像的. zip文件。我想在WPF的一个FlowDocumentReader中显示所有这三个图像。
这是我的代码:

FlowDocument flowDoc = new FlowDocument();
ZipArchive zipFile = ZipFile.OpenRead("images.zip");

foreach (ZipArchiveEntry zip in zipFile.Entries)
{
    Stream imageStream = zip.Open();
    BitmapImage bitmapImage = new BitmapImage();
    bitmapImage.BeginInit();
    bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
    bitmapImage.StreamSource = imageStream;
    bitmapImage.EndInit();
    bitmapImage.DownloadCompleted += BitmapImage_DownloadCompleted;

    Image myImage = new Image
    {
        Source = bitmapImage,
        Stretch = Stretch.Uniform
    };

    BlockUIContainer uiContainer = new BlockUIContainer
    {
        Child = myImage
    };

    flowDoc.Blocks.Add(uiContainer);
}

FlowDocReader.Document = flowDoc;

直到最后一行,它始终可以正常工作,但当FlowDocumentReader加载文档时,会随机出现问题:
有时代码运行良好,并且所有三个图像均显示在FlowDocumentReader中。
有时一些图像显示时会出现一些错误(在一些像素的底线处颜色偏移)。在这种情况下我没有例外。
有时只显示一个、两个或不显示图像。在这种情况下,每个图像有2个未显示的异常:System.dll中的"System. IO. InvalidDataException"。此异常最初是在此调用堆栈中引发的:* * 系统. IO.压缩. inflaterZlib. inflate(系统. IO.压缩. Zlib本机.刷新代码)**
我使用同一个. zip文件得到所有这些随机结果。我可以使用不同的. zip文件重现这个问题。
是我做错了什么,还是有一个已知的bug?

jgzswidk

jgzswidk1#

有些情况下BitmapImage直到最后才读取它的StreamSource。例如,当你从HTTP请求的响应流中读取位图时,可能会发生这种情况。
我还在ZipArchiveEntry.Open()方法返回的Stream中观察到了这一点。
在这些情况下,我的解决方法是将帧缓冲区复制到中间MemoryStream中:

using (var archive = ZipFile.OpenRead("images.zip"))
{
    foreach (var entry in archive.Entries)
    {
        using (var imageStream = entry.Open())
        using (var memoryStream = new MemoryStream())
        {
            imageStream.CopyTo(memoryStream);
            memoryStream.Seek(0, SeekOrigin.Begin);

            var bitmapImage = new BitmapImage();
            bitmapImage.BeginInit();
            bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
            bitmapImage.StreamSource = memoryStream;
            bitmapImage.EndInit();

            ...
        }
    }
}

相关问题