You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Zip压缩包无法完全解压:字节数组解压字节数不符问题

解决SharpZipLib解压时字节数不符的问题

问题根源

你的代码仅调用一次decompressionStream.Read(),但流的Read方法无法保证一次性读取全部数据——它仅返回本次操作实际读取的字节数,当数据量较大或流内部存在缓冲机制时,就会出现读取不完整的情况,导致实际字节数与currentEntry.Size不符。

修正后的代码

Private Function Decompress(ByVal toDecompress As Byte()) As Byte()
    Dim currentEntrySize As Long

    Try
        Using inputStream As New MemoryStream(toDecompress)
            Using decompressionStream As New ICSharpCode.SharpZipLib.Zip.ZipInputStream(inputStream)
                Dim currentEntry As Zip.ZipEntry = decompressionStream.GetNextEntry()
                If currentEntry Is Nothing Then
                    Console.WriteLine("未找到Zip条目")
                    Return Nothing
                End If

                currentEntrySize = currentEntry.Size
                InternalZipFileName = currentEntry.Name

                ' 处理空文件的情况
                If currentEntrySize = 0 Then
                    Return New Byte() {}
                End If

                ' 用MemoryStream存储解压结果,避免大文件数组溢出
                Using outputStream As New MemoryStream()
                    Dim buffer(4095) As Byte ' 4KB缓冲,平衡效率与内存占用
                    Dim bytesRead As Integer

                    ' 循环读取直到流结束
                    Do
                        bytesRead = decompressionStream.Read(buffer, 0, buffer.Length)
                        If bytesRead = 0 Then Exit Do
                        outputStream.Write(buffer, 0, bytesRead)
                    Loop

                    ' 验证最终解压长度是否匹配
                    If outputStream.Length <> currentEntrySize Then
                        Console.WriteLine($"currentEntrySize <> 实际解压长度 - {currentEntrySize}  {outputStream.Length} {InternalZipFileName}")
                        Return Nothing
                    End If

                    Return outputStream.ToArray()
                End Using
            End Using
        End Using
    Catch ex As Exception
        Console.WriteLine($"{ex.Message}{vbCrLf}{ex.StackTrace}")
        Return Nothing
    End Try
End Function

关键修改说明

  • 循环读取流数据:通过Do...Loop持续读取直到流返回0字节,确保所有解压数据被完整读取
  • 改用MemoryStream存储:避免因currentEntry.Size超过Integer.MaxValue导致的数组溢出问题,同时更灵活地处理动态长度数据
  • 增加边界处理:添加空Zip条目、空文件的判断逻辑,覆盖更多异常场景
  • 使用缓冲数组:4KB大小的缓冲是流操作的常规选择,能平衡读取效率与内存占用

内容的提问来源于stack exchange,提问作者Jim wyman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 13:05:15