C#服务端图片打包下载实现代码解析

作者:叶丶梓轩 时间:2023-01-26 07:36:23 

一,设计多图片打包下载逻辑:

1,如果是要拉取腾讯云等资源服务器的图片,

2,我们先把远程图片拉取到本地的临时文件夹,

3,然后压缩临时文件夹,

4,压缩完删除临时文件夹,

5,返回压缩完给用户,

6,用户就去请求下载接口,当下载完后,删除压缩包

二,如下代码,ImageUtil


using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Web;

namespace Common
{
 /// <summary>
 /// 要引用
 /// System.IO.Compression.FileSystem
 /// System.IO.Compression
 /// </summary>
 public static class ImageUtil
 {
   #region 图片打包下载
   /// <summary>
   /// 下载图片到本地,压缩
   /// </summary>
   /// <param name="urlList">图片列表</param>
   /// <param name="curDirName">要压缩文档的路径</param>
   /// <param name="curFileName">压缩后生成文档保存路径</param>
   /// <returns></returns>
   public static bool ImagePackZip(List<string> urlList, string curDirName, string curFileName)
   {
     return CommonException(() =>
     {
       //1.新建文件夹
       if (!Directory.Exists(curDirName))
         Directory.CreateDirectory(curDirName);

//2.下载文件到服务器临时目录
       foreach (var url in urlList)
       {
         DownPicToLocal(url, curDirName + "\\");
         Thread.Sleep(60);//加个延时,避免上一张图还没下载完就执行下一张图的下载操作
       }

//3.压缩文件夹
       if (!File.Exists(curFileName))
         ZipFile.CreateFromDirectory(curDirName, curFileName); //压缩

//异步删除压缩前,下载的临时文件
       Task.Run(() =>
       {
         if (Directory.Exists(curDirName))
           Directory.Delete(curDirName, true);
       });
       return true;
     });
   }
   /// <summary>
   /// 下载压缩包
   /// </summary>
   /// <param name="targetfile">目标临时文件地址</param>
   /// <param name="filename">文件名</param>
   public static bool DownePackZip(string targetfile, string filename)
   {
     return CommonException(() =>
     {
       FileInfo fileInfo = new FileInfo(targetfile);
       HttpResponse rs = System.Web.HttpContext.Current.Response;
       rs.Clear();
       rs.ClearContent();
       rs.ClearHeaders();
       rs.AddHeader("Content-Disposition", "attachment;filename=" + $"{filename}");
       rs.AddHeader("Content-Length", fileInfo.Length.ToString());
       rs.AddHeader("Content-Transfer-Encoding", "binary");
       rs.AddHeader("Pragma", "public");//这两句解决https的cache缓存默认不给权限的问题
       rs.AddHeader("Cache-Control", "max-age=0");
       rs.ContentType = "application/octet-stream";
       rs.ContentEncoding = System.Text.Encoding.GetEncoding("gb2312");
       rs.WriteFile(fileInfo.FullName);
       rs.Flush();
       rs.End();
       return true;
     });
   }

/// <summary>
   /// 下载一张图片到本地
   /// </summary>
   /// <param name="url"></param>
   public static bool DownPicToLocal(string url, string localpath)
   {
     return CommonException(() =>
     {
       string fileprefix = DateTime.Now.ToString("yyyyMMddhhmmssfff");
       var filename = $"{fileprefix}.jpg";

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
       request.Timeout = 60000;
       WebResponse response = request.GetResponse();
       using (Stream reader = response.GetResponseStream())
       {
         FileStream writer = new FileStream(localpath + filename, FileMode.OpenOrCreate, FileAccess.Write);
         byte[] buff = new byte[512];
         int c = 0; //实际读取的字节数
         while ((c = reader.Read(buff, 0, buff.Length)) > 0)
         {
           writer.Write(buff, 0, c);
         }
         writer.Close();
         writer.Dispose();
         reader.Close();
         reader.Dispose();
       }
       response.Close();
       response.Dispose();

return true;
     });
   }
   /// <summary>
   /// 公用捕获异常
   /// </summary>
   /// <param name="func"></param>
   /// <returns></returns>
   private static bool CommonException(Func<bool> func)
   {
     try
     {
       return func.Invoke();
     }
     catch (Exception ex)
     {
       return false;
     }
   }
   #endregion
 }
}

三,测试MVC代码


using Common;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Web.Mvc;

namespace PackImageZip.Controllers
{
 public class HomeController : Controller
 {
   private static object obj = new object();
   public ActionResult Contact()
   {
     ///锁,多文件请求打包,存在并 * 况
     lock (obj)
     {
       var DownPicpath = System.Web.HttpContext.Current.Server.MapPath("/DownPicPackge");//服务器临时文件目录  
       string curFileName = DateTime.Now.ToString("yyyyMMddHHmmssfff") + ".zip";
       ///多次请求文件名一样,睡眠一下
       Thread.Sleep(2000);
       ////保存拉取服务器图片文件夹
       string curDirName = $"/{DateTime.Now.ToString("yyyyMMddHHmmssfff")}/";

List<string> urlList = new List<string>();
       urlList.Add("https://cdn.duitang.com/uploads/item/201409/08/20140908155026_RdUwH.thumb.700_0.jpeg");
       urlList.Add("https://cdn.duitang.com/uploads/item/201409/08/20140908155026_RdUwH.thumb.700_0.jpeg");
       urlList.Add("https://cdn.duitang.com/uploads/item/201409/08/20140908155026_RdUwH.thumb.700_0.jpeg");
       urlList.Add("https://cdn.duitang.com/uploads/item/201409/08/20140908155026_RdUwH.thumb.700_0.jpeg");
       var isOk = ImageUtil.ImagePackZip(urlList, DownPicpath + curDirName, $"{DownPicpath}/{curFileName}");
       var json = JsonConvert.SerializeObject(new { isok = isOk.ToString(), curFileName = curDirName });
       return Content(json);
     }
   }
   /// <summary>
   /// 下载压缩包
   /// </summary>
   /// <param name="curFileName">文件名</param>
   /// <returns></returns>
   public ActionResult DownePackZip(string curFileName)
   {
     try
     {
       curFileName = curFileName + ".zip";
       var DownPicpath = System.Web.HttpContext.Current.Server.MapPath("/DownPicPackge");
       var flag = ImageUtil.DownePackZip(DownPicpath + "/" + curFileName, curFileName);

////flag返回包之后就可以删除包,因为包的已经转为流返回给客户端,无需读取源文件
       if (flag && Directory.Exists(DownPicpath))
         System.IO.File.Delete(DownPicpath + "/" + curFileName);
       return Content(flag.ToString());
     }
     catch (Exception ex)
     {
       return Content(ex.Message);
     }

}
 }
}

来源:https://www.cnblogs.com/May-day/p/11776036.html

标签:C#,服务端,图片,下载
0
投稿

猜你喜欢

  • 在Unity中捕捉Android的常用按钮返回事件

    2023-01-31 00:11:36
  • Android使用fragment实现左侧导航

    2023-10-30 10:02:09
  • Android PickerView实现三级联动效果

    2023-02-25 15:05:47
  • 深入讲解Java Maven配置

    2022-07-01 05:09:21
  • c++野指针的原理以及避免方法

    2023-10-07 09:18:53
  • Java去重排序之Comparable与Comparator的使用及说明

    2023-04-28 00:49:27
  • Android使用AsyncQueryHandler实现获取手机联系人功能

    2021-07-30 20:12:00
  • Java多线程之同步工具类Exchanger

    2022-07-05 03:50:54
  • Java读取TXT文件内容的方法

    2023-11-23 22:33:41
  • C语言折半查找法的超详细讲解

    2022-10-26 19:33:16
  • C# 装箱和拆箱的知识回顾

    2022-07-19 09:27:58
  • .Net WInform开发笔记(二)Winform程序运行结构图及TCP协议在Winform中的应用

    2021-08-08 23:56:44
  • Spring JPA 错题集解决案例

    2022-03-26 22:44:03
  • Java 实现协程的方法

    2022-02-18 22:55:05
  • android使用OPENGL ES绘制圆柱体

    2021-12-26 15:22:00
  • Android编程开发之TextView控件用法(2种方法)

    2023-09-19 02:24:02
  • 详解C#借助.NET框架中的XmlTextReader类读取XML的方法

    2023-01-18 23:31:47
  • 关于idea中Java Web项目的访问路径问题

    2023-01-04 21:23:32
  • C#中的引用类型以及特殊引用类型详解

    2023-06-18 01:43:46
  • Android 基于百度语音的语音交互功能(推荐)

    2021-08-22 01:26:38
  • asp之家 软件编程 m.aspxhome.com