c#服务端图片打包下载

一,设计多图片打包下载逻辑:
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);
            }

        }
    }
}

 

posted @ 2019-11-01 11:32  叶丶梓轩  阅读(999)  评论(0编辑  收藏  举报