需求:上传一个.zip的压缩包,压缩包内有很多照片文件(格式:123568.jpg或56448486.png),根据文件名称(除文件后缀),进行用户信息头像保存和更新
环境: .NET6.0 WebApi项目
解决方案
将压缩文件保存到本地
- 将压缩文件保存到本地
- 解压缩到指定文件夹内
- 循环遍历文件夹内文件读取文件流进行操作
- 使用完成后释放资源并删除文件夹和文件
这样操作可能会因为资源问题造成不必要的异常
读取到内存中
- 在内存中进行操作简化了文件在本地读取过程,提高了处理速度和资源处理能力
文件不落地处理
代码及说明
使用 ZipArchive 进行压缩文件的操作
using System.IO.Compression;
using Microsoft.AspNetCore.Mvc;
namespace UploadFileToMemory.Controllers;
[ApiController]
[Route("[controller]")]
public class UploadFileController : ControllerBase
{
/// <summary>
/// 文件不落地处理
/// </summary>
/// <param name="file"></param>
/// <exception cref="Exception"></exception>
public async Task UploadFileToMemory(IFormFile file)
{
// 检查是否有文件
if (file == null) throw new Exception("文件不能为空");
// 检查文件后缀
var fileExtension = Path.GetExtension(file.FileName);
if (fileExtension == null) throw new Exception("文件后缀不能为空");
// 检查文件后缀是否为zip
if (fileExtension.ToLower() != ".zip") throw new Exception("文件后缀必须为zip");
// 解压文件到内存流
await using var memoryStream = new MemoryStream();
await file.CopyToAsync(memoryStream);
// 检查压缩包中是否有文件
using var archive = new ZipArchive(memoryStream);
var entries = archive.Entries;
if (entries.Count == 0) throw new Exception("压缩包中未找到文件");
// 检查压缩包中的文件是否为图片
var isImage = entries.Any(it => it.Name.EndsWith(".jpg") || it.Name.EndsWith(".png"));
if (!isImage) throw new Exception("压缩包中未找到图片");
// 循环遍历上传图片
foreach (var zipArchiveEntry in entries)
{
// 检查文件后缀
var entryExtension = Path.GetExtension(zipArchiveEntry.Name);
if (string.IsNullOrWhiteSpace(entryExtension)) continue;
// 检查文件后缀是否为图片,否则跳过
if (entryExtension.ToLower() != ".jpg" && entryExtension.ToLower() != ".png") continue;
// 创建一个entry的内存流
await using var entryMemoryStream = new MemoryStream();
await using var entryStream = zipArchiveEntry.Open();
await entryStream.CopyToAsync(entryMemoryStream);
entryMemoryStream.Position = 0;
// 生成FormFile
var formFile = new FormFile(entryMemoryStream, 0, entryMemoryStream.Length, null!, zipArchiveEntry.Name)
{
Headers = new HeaderDictionary(),
ContentType = entryExtension.ToLower() == ".jpg" ? "image/jpeg" : "image/png"
};
// 对formFile进行业务处理 如上传到oos/ftp/local等,可以进行集中处理
}
}
}