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     /// <summary>
 12     /// Zip辅助类
 13     /// </summary>
 14     public static class ZipHelperExtension
 15     {
 16         /// <summary>
 17         /// 解压单zip压缩文件
 18         /// </summary>
 19         /// <param name="sourceFile">压缩文件</param>
 20         /// <param name="contentHandle">文本内容处理</param>
 21         /// <returns>压缩的所有文件处理结果</returns>
 22         public static async Task<(IList<T> modelList, string errMessage)> UnZipFileAsync<T>(IFormFile sourceFile,
 23             Func<string, Task<T>> contentHandle) where T : class
 24         {
 25             var err = string.Empty;
 26             var modelList = new List<T>();
 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         /// <summary>
 43         /// 批量解压zip压缩文件
 44         /// </summary>
 45         /// <param name="sourceFiles">压缩文件</param>
 46         /// <param name="contentHandle">文本内容处理</param>
 47         /// <returns>压缩的所有文件处理结果</returns>
 48         public static async Task<(IList<T> list, string err)> UnZipFilesAsync<T>(IFormFileCollection sourceFiles,
 49             Func<string, Task<T>> contentHandle) where T : class
 50         {
 51             var err = string.Empty;
 52             var list = new List<T>();
 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         /// <summary>
 64         /// 处理zip压缩文件内容
 65         /// </summary>
 66         /// <param name="zipIn">压缩文件流</param>
 67         /// <param name="contentHandle">文本内容处理</param>
 68         /// <returns>压缩的所有文件处理结果集合</returns>
 69         public static async Task<IEnumerable<T>> UnZipAsync<T>(ZipInputStream zipIn, 
 70             Func<string, Task<T>> contentHandle) where T : class
 71         {
 72             var list = new List<T>();
 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         /// <summary>
102         /// 获取文本流
103         /// </summary>
104         /// <param name="str">字符串</param>
105         /// <returns>文本流</returns>
106         public static async Task<Stream> 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         /// <summary>
120         /// 获取文本流内容
121         /// </summary>
122         /// <param name="textStream">文本流</param>
123         /// <returns>文本流内容</returns>
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 }
View Code

  

  上传文件测试一下用法:

 1         /// <summary>
 2         /// 解压zip测试
 3         /// </summary>
 4         /// <param name="zipFile">压缩文件</param>
 5         /// <returns></returns>
 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<Person>(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         }
View Code

 

  

结果: 

posted @ 2022-01-25 22:15  JN-SHao  阅读(66)  评论(0编辑  收藏  举报