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

在ASP.NET Core 6.0中如何读取嵌套Zip文件中.dat文件的文本内容?

问题描述

我上传的是IFormFile类型的Zip文件,该Zip内包含多个文件夹,文件夹中又嵌套了Zip文件,这些嵌套Zip里有.dat格式文件,我需要读取这些.dat文件的文本内容。

我尝试了以下代码:

[HttpPost]
public async Task<IActionResult> RequestFiles()
{
    try
    {
        IFormFile file = Request.Form.Files[0];
        Stream stream = file.OpenReadStream();
        using (ZipArchive archive = new ZipArchive(stream, ZipArchiveMode.Read))
        {
            foreach (var entry in archive.Entries)
            {
                if (entry.Name.ToLower().Contains(".zip"))
                {
                    MemoryStream nestedArchiveStream = new MemoryStream();

                    entry.Open().CopyTo(nestedArchiveStream);
                    
                    using (var nestedArchive = new ZipArchive(nestedArchiveStream))
                    {
                        var datFile = nestedArchive.Entries[0];

                        StreamReader reader = new StreamReader(datFile.ToString());
                        string strAllFile = reader.ReadToEnd();
                    }
                }
            }
        }
        return Ok();
    }
    catch (Exception ex)
    {
        return BadRequest(ex.Message);
    }
}

但出现错误:

错误:找不到文件 'D:\project'spath\WPNN788_4_11-15-22_084023.dat'。


错误原因与修正方案

核心错误点

代码中StreamReader reader = new StreamReader(datFile.ToString());是问题根源:datFile.ToString()返回的是Zip条目的名称,而非可读取的流或本地路径,StreamReader会错误地尝试在本地磁盘查找该文件,自然找不到。

修正后的代码

[HttpPost]
public async Task<IActionResult> RequestFiles()
{
    try
    {
        IFormFile file = Request.Form.Files[0];
        using (Stream stream = file.OpenReadStream())
        using (ZipArchive archive = new ZipArchive(stream, ZipArchiveMode.Read))
        {
            foreach (var entry in archive.Entries)
            {
                // 跳过文件夹条目(Zip中文件夹的Name为空)
                if (string.IsNullOrEmpty(entry.Name))
                    continue;

                if (entry.Name.EndsWith(".zip", StringComparison.OrdinalIgnoreCase))
                {
                    using (MemoryStream nestedArchiveStream = new MemoryStream())
                    {
                        // 异步复制嵌套Zip内容到内存流
                        await entry.Open().CopyToAsync(nestedArchiveStream);
                        // 重置流位置到开头,否则ZipArchive无法读取内容
                        nestedArchiveStream.Position = 0;

                        using (var nestedArchive = new ZipArchive(nestedArchiveStream, ZipArchiveMode.Read))
                        {
                            foreach (var nestedEntry in nestedArchive.Entries)
                            {
                                // 跳过文件夹,仅处理.dat文件
                                if (string.IsNullOrEmpty(nestedEntry.Name) || !nestedEntry.Name.EndsWith(".dat", StringComparison.OrdinalIgnoreCase))
                                    continue;

                                // 直接打开.dat条目流读取内容
                                using (Stream datStream = nestedEntry.Open())
                                using (StreamReader reader = new StreamReader(datStream))
                                {
                                    string datContent = await reader.ReadToEndAsync();
                                    // 此处可添加对dat内容的处理逻辑(如存储、返回等)
                                }
                            }
                        }
                    }
                }
            }
        }
        return Ok();
    }
    catch (Exception ex)
    {
        return BadRequest(ex.Message);
    }
}

关键优化点

  1. 流读取修正:用nestedEntry.Open()获取.dat文件的流,替代错误的datFile.ToString(),直接读取Zip内的文件内容。
  2. 流位置重置:复制内容到MemoryStream后,必须设置Position = 0,否则ZipArchive会从流的末尾开始读取,导致无法识别有效内容。
  3. 条目过滤:添加文件夹判断和.dat文件筛选,避免误处理非目标文件。
  4. 异步优化:使用CopyToAsync和ReadToEndAsync,符合异步方法的性能最佳实践,避免阻塞线程。

内容的提问来源于stack exchange,提问作者dawood abbas

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 05:35:10