当前位置:主页 > 软件编程 > .NET代码 >

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

时间:2020-11-16 12:01:11 | 栏目:.NET代码 | 点击:

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

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);
      }

    }
  }
}

您可能感兴趣的文章:

相关文章