在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); } }
关键优化点
- 流读取修正:用
nestedEntry.Open()获取.dat文件的流,替代错误的datFile.ToString(),直接读取Zip内的文件内容。 - 流位置重置:复制内容到MemoryStream后,必须设置
Position = 0,否则ZipArchive会从流的末尾开始读取,导致无法识别有效内容。 - 条目过滤:添加文件夹判断和.dat文件筛选,避免误处理非目标文件。
- 异步优化:使用
CopyToAsync和ReadToEndAsync,符合异步方法的性能最佳实践,避免阻塞线程。
内容的提问来源于stack exchange,提问作者dawood abbas
相关产品推荐
相关产品推荐

