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

.NET 8中ZipFileEntry流读取不完整,无法正确复制ZIP文件内容到字节数组

.NET 8中ZipFileEntry流读取不完整,无法正确复制ZIP文件内容到字节数组

你遇到的这个问题其实是流读取的常见坑——Stream.Read()方法并不会保证一次性读取你指定的所有字节,它只会返回实际成功读取的字节数。这在处理ZipArchiveEntry打开的压缩流时特别明显,因为这类流是分块解压并返回数据的,不会一下子把所有内容都加载到内存里。

你看你的代码里只调用了一次Read(rawData, 0, rawData.Length),如果文件实际内容是100KB,但这次调用可能只读到了一部分,剩下的还留在流里没被读取,所以输出的readBytes会比预期的100KB小。

下面给你几个实用的解决办法:

方案一:循环读取直到流结束

通过循环不断调用Read方法,直到返回值为0(表示流已经读完),把每次读取到的字节拼接起来:

using System;
using System.IO.Compression;
using System.IO;

namespace ConsoleApp2
{
    internal class Program
    {
        static void Main(string[] args)
        {
            using var zipfile = ZipFile.OpenRead("Test.zip");
            var zipfileEntry = zipfile.GetEntry("Data20240810");
            if (zipfileEntry == null)
            {
                Console.WriteLine("找不到指定的ZIP条目");
                return;
            }
            
            using var fileStream = zipfileEntry.Open();
            using var ms = new MemoryStream();
            
            int readBytes;
            var buffer = new byte[4096]; // 用4KB的缓冲块读取更高效
            while ((readBytes = fileStream.Read(buffer, 0, buffer.Length)) > 0)
            {
                ms.Write(buffer, 0, readBytes);
            }
            
            var rawData = ms.ToArray();
            Console.WriteLine($"读取到的总字节数:{rawData.Length}");
            Console.WriteLine($"ZIP条目的实际大小:{zipfileEntry.Length}");
        }
    }
}

方案二:用CopyTo方法简化代码

Stream.CopyTo()方法内部已经帮你实现了循环读取的逻辑,直接把Zip流的内容复制到MemoryStream,再转成字节数组就行,代码更简洁:

using System;
using System.IO.Compression;
using System.IO;

namespace ConsoleApp2
{
    internal class Program
    {
        static void Main(string[] args)
        {
            using var zipfile = ZipFile.OpenRead("Test.zip");
            var zipfileEntry = zipfile.GetEntry("Data20240810");
            if (zipfileEntry == null)
            {
                Console.WriteLine("找不到指定的ZIP条目");
                return;
            }
            
            using var fileStream = zipfileEntry.Open();
            using var ms = new MemoryStream();
            
            fileStream.CopyTo(ms);
            var rawData = ms.ToArray();
            
            Console.WriteLine($"读取到的总字节数:{rawData.Length}");
            Console.WriteLine($"ZIP条目的实际大小:{zipfileEntry.Length}");
        }
    }
}

最后再提醒几个细节:

  • 一定要用using语句包裹ZipArchive、Stream这些实现了IDisposable的对象,避免资源泄漏。
  • 可以通过zipfileEntry.Length获取条目的实际大小,用来验证读取结果是否正确。
  • 不要固定创建100KB的字节数组,如果条目大小不是刚好100KB,要么浪费空间要么不够用,用MemoryStream动态扩容更灵活。

备注:内容来源于stack exchange,提问作者dovepoppo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.16 07:13:17