记录一次视频文件和图片文件 分别存储在不同的文件夹中 并且合并成一个压缩包的方法

363 阅读1分钟

思路:

  1. 首先将视频文件和图片文件提出来
    • 从方法获取传参的jsondata
    • 遍历jsonData的资源的路径
  2. 创建Temp临时的文件夹,将视频文件和图片文件复制到临时的文件夹
    • 复制资源路径到Temp的特定的文件夹(如jsonData有video,那么就创建一个video文件夹,并且复制视频到这个Temp/Video的文件夹内)
    • dataJson写入到Temp临时文件夹
  3. 创建Zip文件夹,将Temp文件夹的内容复制到Zip文件夹中,然后删除Temp文件夹
    • 创建Zip文件夹
    • 拼凑压缩包完整目录
    • 压缩指定文件到Zip的目录内(也就是将temp的文件,添加到Zip文件内,并且形成压缩包)
  4. 取zip内容 然后返回字节流,删除Temp临时文件夹

实现:

  1. 接口实现类的方法
   public async Task<byte[]> GenerateZipFileAsync(ProgramJson jsonData, string id, string rootPath)
   {
       var pathList = jsonData.ProgramRes.AllResources;

       // 循环并凑Path.Combine
       var resList = new List<string>();
       foreach (string resStr in pathList)
       {
           string modifiedStr = Path.Combine(Directory.GetCurrentDirectory(), resStr.Substring(1).Replace("/", "\\")); // 将/替换为\
           resList.Add(modifiedStr);
       }

       // 创建temp文件夹
       string tempFilePath = Path.Combine(rootPath + "\\Upload\\Temp"); 
       Directory.CreateDirectory(tempFilePath); // 创建文件夹
       var source = new List<string>() { "Video", "Picture", "Audio", "Document" };

       // 将资源文件夹添加进来
       foreach (string sourceStr in source)
       {
           var matchingFiles = resList.Where(r => r.Contains(sourceStr)).ToList();
           foreach (string matchingFile in matchingFiles) // 循环匹配到的文件
           {
               string targetDirectory = Path.Combine(tempFilePath, "Downloads", "Upload", sourceStr);
               Directory.CreateDirectory(targetDirectory);
               // 提取文件名
               string fileName = Path.GetFileName(matchingFile);
               File.Copy(Path.Combine(rootPath, "Upload", sourceStr, fileName), Path.Combine(targetDirectory, fileName), true);
           }
       }
       // 将jsonData写入data.json
       string jsonDataPath = Path.Combine(tempFilePath, "data.json");
       string jsonDataString = "[" + System.Text.Json.JsonSerializer.Serialize(jsonData) + "]"; // 包装在[]
       await File.WriteAllTextAsync(jsonDataPath, jsonDataString);

       // 压缩目标文件夹
       Directory.CreateDirectory(rootPath + "\\Upload\\Zip"); // 创建文件夹
       string zipFileName = $"{jsonData.ProgramName}_{DateTime.Now.ToString("yyyyMMddHHmmss")}.zip";
       string zipFilePath = Path.Combine(rootPath + "\\Upload\\Zip", zipFileName); // 拼凑压缩包完整路径
       ZipFile.CreateFromDirectory(tempFilePath, zipFilePath); // 压缩到指定文件夹

       // 读取ZIP文件的内容并返回
       byte[] zipFileBytes = await File.ReadAllBytesAsync(zipFilePath); // 必须是压缩包

       // 清理临时文件
       Directory.Delete(tempFilePath, true);

       return zipFileBytes;
   }
  1. 控制器的实现
    [HttpPost]
   public async Task<IActionResult> ExportProgram(GenerateDto dto)
   {
       // 先得JSON数据
       ProgramJson data = await _programBusiness.GenerateJsonAsync(dto);
       string wwwrootPaths = _webHostEnvironment.WebRootPath; // wwwroot路径
       if (data == null)
       {
           throw new BusException("Invalid data or topic");
       }
       
       var zipFileBytes = await _fileBusiness.GenerateZipFileAsync(data, dto.Id, wwwrootPaths); // 生成ZIP文件

       var memoryStream = new MemoryStream(zipFileBytes); // 创建内存流对象
       memoryStream.Position = 0; // 设置当前流的位置为流的开始
       string programFileName = $"{data.ProgramName}.zip";
       return File(memoryStream, "application/zip", programFileName);// 返回文件
   }
  1. 下面是生成的目录(Temp文件夹已经删除)

image.png