Stream流应用


  对上传zip压缩文本文件解析,引用第三方包SharpZipLib,写了一个静态扩展类。主要是对Stream流的基本操作方便下次翻看,代码如下:

  1 using ICSharpCode.SharpZipLib.Zip;
  2 using Microsoft.AspNetCore.Http;
  3 using System;
  4 using System.Collections.Generic;
  5 using System.IO;
  6 using System.Text;
  7 using System.Threading.Tasks;
  8 
  9 namespace Extensions
 10 {
 11     /// 
 12     /// Zip辅助类
 13     /// 
 14     public static class ZipHelperExtension
 15     {
 16         /// 
 17         /// 解压单zip压缩文件
 18         /// 
 19         /// 压缩文件
 20         /// 文本内容处理
 21         /// 压缩的所有文件处理结果
 22         public static async Task<(IList modelList, string errMessage)> UnZipFileAsync(IFormFile sourceFile,
 23             Func<string, Task> contentHandle) where T : class
 24         {
 25             var err = string.Empty;
 26             var modelList = new List();
 27             try
 28             {
 29                 await using ZipInputStream zipIn = new(sourceFile.OpenReadStream());
 30 
 31                 var models = await UnZipAsync(zipIn, contentHandle);
 32                 modelList.AddRange(models);
 33             }
 34             catch (Exception ex)
 35             {
 36                 err = $"错误信息=>{sourceFile.Name}:{ex.Message};";
 37             }
 38 
 39             return (modelList, err);
 40         }
 41 
 42         /// 
 43         /// 批量解压zip压缩文件
 44         /// 
 45         /// 压缩文件
 46         /// 文本内容处理
 47         /// 压缩的所有文件处理结果
 48         public static async Task<(IList list, string err)> UnZipFilesAsync(IFormFileCollection sourceFiles,
 49             Func<string, Task> contentHandle) where T : class
 50         {
 51             var err = string.Empty;
 52             var list = new List();
 53             foreach (var sourceFile in sourceFiles)
 54             {
 55                 var (modelList, errMessage) = await UnZipFileAsync(sourceFile, contentHandle);
 56                 list.AddRange(modelList);
 57                 err += errMessage;
 58             }
 59 
 60             return (list, err);
 61         }
 62 
 63         /// 
 64         /// 处理zip压缩文件内容
 65         /// 
 66         /// 压缩文件流
 67         /// 文本内容处理
 68         /// 压缩的所有文件处理结果集合
 69         public static async Task> UnZipAsync(ZipInputStream zipIn, 
 70             Func<string, Task> contentHandle) where T : class
 71         {
 72             var list = new List();
 73             while (zipIn.GetNextEntry() != null)
 74             {
 75                 Stream stream = new MemoryStream();
 76                 await using var bos = new BinaryWriter(stream, Encoding.Default, leaveOpen: false);
 77 
 78                 var bytes = new byte[1024];
 79                 while (true)
 80                 {
 81                     var len = await zipIn.ReadAsync(bytes);
 82                     if (len <= 0)
 83                     {
 84                         break;
 85                     }
 86 
 87                     bos.Write(bytes, 0, len);
 88                     bos.Flush();
 89                 }
 90 
 91                 if (stream.Length == 0) continue;//过滤文件夹
 92                 stream.Position = 0;
 93                 var content = await GetTextStreamContentAsync(stream);
 94                 var model = await contentHandle(content);
 95                 list.Add(model);
 96             }
 97 
 98             return list;
 99         }
100 
101         /// 
102         /// 获取文本流
103         /// 
104         /// 字符串
105         /// 文本流
106         public static async Task GetStreamAsync(this string str)
107         {
108             var stream = new MemoryStream();
109             //leaveOpen:true使StreamWriter释放而stream不会释放
110             await using var writer = new StreamWriter(stream, leaveOpen: true);
111 
112             await writer.WriteAsync(str);
113             await writer.FlushAsync();
114 
115             stream.Position = 0;
116             return stream;
117         }
118 
119         /// 
120         /// 获取文本流内容
121         /// 
122         /// 文本流
123         /// 文本流内容
124         public static async Task<string> GetTextStreamContentAsync(Stream textStream)
125         {
126             using var reader = new StreamReader(textStream);
127             return await reader.ReadToEndAsync();
128         }
129     }
130 }

  上传文件测试一下用法:

 1         /// 
 2         /// 解压zip测试
 3         /// 
 4         /// 压缩文件
 5         /// 
 6         [HttpPost("unzip-test")]
 7         //这个注意IFormFile,IFormFileCollection类型前面不需要直接加[FromForm]特性,否者swagger不支持上传文件
 8         //可以将表单所有参数(包括文件IFormFile,IFormFileCollection)封装一个参数对象,前面加[FromForm]特性
 9         public async Task UnzipTest(IFormFile zipFile)
10         {
11             var (persons, errMessage) = await ZipHelperExtension.UnZipFileAsync(zipFile,
12                 async content =>
13             {
14                 var person = JsonConvert.DeserializeObject(content);
15                 person?.Pets.Add(new Pet() { Name = "小猪", Age = 5 });
16                 person?.Pets.ForEach(p => p.Master = person);
17                 return await Task.FromResult(person);
18             });
19             _logger.LogInformation(string.Join("\n", persons));
20         }

结果: 

相关