新工作,第一个小任务,制作一个点击下载图片的功能。并提供批量下载操作。图片是字节流的形式,存放在数据库中的。

为了避免直接从数据库中,下载失败,会在本地保存一份。

进行压缩的是SharpZip这个压缩帮助类。

首先,创建一个实体,用来存放字节流这些

  1. public class ATLRLAttachment
  2. {
  3. /// <summary>
  4. /// 字节流
  5. /// </summary>
  6. public byte[] FileContent { get; set; }
  7.  
  8. /// <summary>
  9. /// 类型
  10. /// </summary>
  11. public string FileExt { get; set; }
  12.  
  13. /// <summary>
  14. /// 名称
  15. /// </summary>
  16. public string FileName { get; set; }
  17. }

主要是针对这个实体,进行的字节流和名称的读取。因为要自动保存,而且这个功能是可选的,所以我用一个枚举来控制,是否可以执行这个方法。

定义枚举如下:

  1. /// <summary>
  2. /// 是否自动保存
  3. /// add by chenxy 16.3.10
  4. /// </summary>
  5. public enum IsSaveImage
  6. {
  7. Save = ,
  8. NotSave =
  9. }

我是本地机进行的测试,所以字节流模拟工作是从图片进行转换的。那么加上这个图片转换方法。

  1. /// <summary>
  2. /// 通过图片地址将图片转换成字节流
  3. /// add by chenxy 16.3.10
  4. /// </summary>
  5. /// <param name="url">图片地址</param>
  6. /// <returns>字节流</returns>
  7. public byte[] GetImageByte(string url)
  8. {
  9. FileStream fs = new FileStream(url, FileMode.Open);
  10. byte[] byData = new byte[fs.Length];
  11. fs.Read(byData, , byData.Length);
  12. fs.Close();
  13. return byData;
  14. }

打开图片,进行缓冲区,然后把字节流返回。比较懒,没做异常处理。

接下来,是临时保存功能。

  1. /// <summary>
  2. /// 图片临时保存功能
  3. /// add by chenxy 16.3.10
  4. /// <param name="saveByte">字节流</param>
  5. /// <param name="strName">图片名称</param>
  6. /// <param name="strExt">图片后缀</param>
  7. /// <returns>文件路径</returns>
  8. /// </summary>
  9. public string SaveImage(byte[] saveByte, string strName, string strExt)
  10. {
  11. string path = AppDomain.CurrentDomain.BaseDirectory;
  12. string url = string.Format(@"{0}TemporaryImage", path);
  13. path = string.Format(@"{0}\\{1}", url, strName);
  14. //判断目录
  15. if (!Directory.Exists(url))
  16. {
  17. Directory.CreateDirectory(url);
  18. }
  19. //判断文件
  20. if (File.Exists(path))
  21. {
  22. File.Delete(path);
  23. }
  24. MemoryStream fs = new MemoryStream(saveByte);
  25. Image img = Image.FromStream(fs);
  26. ImageFormat imgFormat = ImageFormat.Jpeg;
  27. switch (strExt)
  28. {
  29. case ".bmp":
  30. imgFormat = ImageFormat.Bmp;
  31. break;
  32. case ".png":
  33. imgFormat = ImageFormat.Png;
  34. break;
  35. case ".gif":
  36. imgFormat = ImageFormat.Gif;
  37. break;
  38. }
  39. img.Save(path, imgFormat);
  40. return path;
  41. }

Directory 操作目录,File 操作文件,然后用Image进行最后的保存图片。

然后是单个下载功能代码

  1. public void ImageDown(HttpContext context, ATLRLAttachment model, IsSaveImage save)
  2. {
  3. #region 验证方法
  4. if (model.FileContent == null || model.FileContent.Length < )
  5. {
  6. ErrorMessage(context, "下载链接中没有对应的图片");
  7. return;
  8. }
  9. #endregion
  10. #region 是否临时保存
  11. if (save == IsSaveImage.Save)
  12. {
  13. string strUrl = SaveImage(model.FileContent, model.FileName);
  14. model.FileContent = GetImageByte(strUrl);
  15. }
  16. #endregion
  17. context.Response.AddHeader("Content-Disposition", string.Format("attachment;filename={0}", model.FileName));
  18. context.Response.ContentType = string.Format("image/{0}", model.FileExt.Replace(".", ""));
  19. context.Response.BinaryWrite(model.FileContent);
  20. context.Response.Flush();
  21. context.Response.Close();
  22. }

其中ErrorMessage 是提示信息。

  1. public void ErrorMessage(HttpContext context, string strMsg)
  2. {
  3. context.Response.Write(string.Format("<script language=javascript>alert('{0}');</" + "script>", strMsg));
  4. context.Response.Write("<script language=javascript>history.go(-1);</script>");
  5. context.Response.End();
  6. }

批量下载使用的重载,通过传递IEnumerable 进行批量压缩。

  1. /// <summary>
  2. /// 批量下载
  3. /// add by chenxy 16.3.10
  4. /// </summary>
  5. /// <param name="context">HTTP请求</param>
  6. /// <param name="models">下载集合</param>
  7. public void ImageDown(HttpContext context, IEnumerable<ATLRLAttachment> models, IsSaveImage save)
  8. {
  9. string FileToZip = DateTime.Now.ToString("yyyymmdd") + ".zip";
  10. string path = AppDomain.CurrentDomain.BaseDirectory;
  11. string url = string.Format(@"{0}TemporaryImage", path);
  12. path = string.Format(@"{0}\\{1}", url, FileToZip);
  13. BatchDeleteZip(url);
  14. using (FileStream ms = File.Create(path))
  15. {
  16. using (ZipOutputStream zip = new ZipOutputStream(ms))
  17. {
  18. zip.SetLevel();
  19. int itFileNameNum = ;
  20. foreach (ATLRLAttachment m in models)
  21. {
  22. #region 修改重名文件
  23. if (models.Where(p => p.FileName == m.FileName).Count() > )
  24. {
  25. itFileNameNum++;
  26. try
  27. {
  28. m.FileName = m.FileName.Insert(m.FileName.IndexOf("."), string.Format("_{0}", itFileNameNum));
  29. }
  30. catch (ArgumentNullException)
  31. {
  32. ErrorMessage(context, string.Format("文件名:{0},格式错误,未包含后缀连接符.", m.FileName));
  33. return;
  34. }
  35. }
  36. #endregion
  37. #region 是否临时保存
  38. if (save == IsSaveImage.Save)
  39. {
  40. string strUrl = SaveImage(m.FileContent, m.FileName, m.FileExt);
  41. m.FileContent = GetImageByte(strUrl);
  42. //判断文件
  43. if (File.Exists(strUrl))
  44. {
  45. File.Delete(strUrl);
  46. }
  47. }
  48. #endregion
  49. //如果没有图片就跳过
  50. if (m.FileContent == null || m.FileContent.Length < )
  51. {
  52. continue;
  53. }
  54. ZipEntry entry = new ZipEntry(m.FileName);
  55. zip.PutNextEntry(entry);
  56. zip.Write(m.FileContent, , m.FileContent.Length);
  57. }
  58. zip.Finish();
  59. zip.Close();
  60. }
  61. }
  62. FileInfo fileInfo = new FileInfo(path);
  63. context.Response.Clear();
  64. context.Response.ClearContent();
  65. context.Response.ClearHeaders();
  66. context.Response.AddHeader("Content-Disposition", string.Format("attachment;filename={0}.zip", DateTime.Now.ToString("yyyyMMdd")));
  67. context.Response.AddHeader("Content-Length", fileInfo.Length.ToString());
  68. context.Response.AddHeader("Content-Transfer-Encoding", "binary");
  69. context.Response.ContentType = "application/octet-stream";
  70. context.Response.ContentEncoding = System.Text.Encoding.GetEncoding("utf-8");
  71. context.Response.WriteFile(fileInfo.FullName);
  72. context.Response.Flush();
  73. context.Response.End();
  74. }

批量下载需要删除文件夹,有一个遍历目录并删除文件的方法

  1. /// <summary>
  2. /// 批量删除压缩包
  3. /// add by chenxy 16.3.15
  4. /// </summary>
  5. /// <param name="strUrl">压缩包路径</param>
  6. public void BatchDeleteZip(string strUrl)
  7. {
  8. //判断路径是否为空
  9. if (string.IsNullOrEmpty(strUrl))
  10. {
  11. throw new ArgumentNullException("文件目录为空");
  12. }
  13. //判断是否有目录
  14. if (!Directory.Exists(strUrl))
  15. {
  16. return;
  17. }
  18. //获取目录下所有文件
  19. string[] strFiles = Directory.GetFiles(strUrl);
  20. //判断文件时间长短
  21. foreach (string strfile in strFiles)
  22. {
  23. FileInfo info = new FileInfo(strfile);
  24. if (info.CreationTime.DistanceToday() >= )
  25. {
  26. File.Delete(info.FullName);
  27. }
  28.  
  29. }
  30. }

最后就没的说了,就是普通的调用测试,写的比较乱,勉强能看懂

  1. public void ProcessRequest(HttpContext context)
  2. {
  3. // string path = AppDomain.CurrentDomain.BaseDirectory;
  4. //byte[] result = GetImageByte(string.Format(@"{0}0.jpg", path));
  5. //path = SaveImage(result,"0.jpg");
  6. //result = GetImageByte(path);
  7.  
  8. byte[] result = GetImageByte(@"D://111.jpg");
  9. ImageDown(context, new ATLRLAttachment { FileContent = result, FileExt = ".jpg", FileName = "ce.jpg" }, IsSaveImage.Save);
  10. // File.Delete(path);
  11. return;
  12. //ImageDown(context, result, "imageName.jpg", "jpg");
  13.  
  14. var list = new[] { new ATLRLAttachment { FileContent = result, FileExt = ".jpg", FileName = "Name.jpg" }, new ATLRLAttachment { FileContent = result, FileExt = ".jpg", FileName = "Name.jpg" } };
  15. ImageDown(context, list, IsSaveImage.Save);
  16. return;
  17.  
  18. }

程序员最有利的武器,就是谷歌,百度。做这个的时候,我就想,用IO流进行保存。但是忘记方法名了,就一直尴尬。

下载地址:https://coding.net/u/chenxygx/p/CodeSave/git/blob/master/Handler1.ashx.cs

记录一下,免得以后再去百度了。By~

C#实体图片下载与批量下载(自动保存功能)的更多相关文章

  1. 用汇编语言给XP记事本添加“自动保存”功能 good

    [文章标题]: 用汇编语言给XP记事本添加“自动保存”功能 [文章作者]: newjueqi [作者邮箱]:zengjiansheng1@126.com [作者QQ]:190678908 [使用工具] ...

  2. PyCharm 去掉自动保存功能

    PyCharm 4.5.4 环境配置 1.去掉"自动保存功能" pycharm默认是自动保存的,习惯自己按 ctrl + s 的可以进行如下设置: 菜单File -> Set ...

  3. 第四十一篇-android studio 关闭自动保存功能

    此方法不可用. 第一步:取消自动保存功能 File > Settings > Appearance & Behavior > System Settings > Syn ...

  4. Intellij IDEA 开启自动保存功能

    IntelljJ IDEA关于文件自动保存功能主要有两种方式: 切换到其他应用时保存变化(默认使能) 设置路径:Settings >> Apperance & Behavior & ...

  5. 【工具】Sublime Text 自动保存功能

    经常需要所以要频繁用到"ctrl+s"保存还是挺麻烦的,所以有的人需要用到失去焦点自动保存功能,这里简单记录下 1.点击"Preferences"里的设置-用户 ...

  6. WebStorm 编辑器 关闭自动保存功能及添加*星星标记

    WebStorm 关闭自动保存功能添加*星星标记为什么要关闭自动保存?      ​ 在前端项目工作当中,往往会采用自动化环境(Gulp.webpack等)当文本发生变化的时候就会自动编译代码.在we ...

  7. 关于vscode自动跳转回车的解决方法(关闭vscode自动保存功能;可能和其他插件有冲突)

    关于vscode自动跳转回车的解决方法(关闭vscode自动保存功能:可能和其他插件有冲突)

  8. 通过HttpURLConnection下载图片到本地--批量下载

    一.背景说明 这篇文章讲述的是批量下载附件,在上一篇文章中,介绍了下载单个附件(上一篇文章). 二.实现思路 主要的实现思路:创建文件夹->文件夹中创建需要下载的文件->压缩文件夹-> ...

  9. JAVA SFTP文件上传、下载及批量下载

    JavaJsch  1.jsch官方API查看地址(附件为需要的jar) http://www.jcraft.com/jsch/ 2.jsch简介 JSch(Java Secure Channel)是 ...

随机推荐

  1. Qt学习笔记 ListWidget的增删改

    学习了一下ListWidget控件的使用,做一个小功能增删改 先把代码分解最后给出完整代码 在窗体上添加一个ListWidget 一个Horizontal Specer和  三个PushButton ...

  2. servlet乱码问题总结

    在学习时servlet乱码问题还是挺严重的,总结一下有三种情况 1.新建HTML页面后浏览出现乱码 2.以post形式请求时出现乱码 3.以get形式请求时出现乱码 让我们一个一个来解决吧 1.新建H ...

  3. deep learning 的综述

    从13年11月初开始接触DL,奈何boss忙or 各种问题,对DL理解没有CSDN大神 比如 zouxy09等 深刻,主要是自己觉得没啥进展,感觉荒废时日(丢脸啊,这么久....)开始开文,即为记录自 ...

  4. HoloLens开发手记 - 应用程序模型 App model

    HoloLens使用Universal Windows Platform (UWP)提供的应用模型.UWP应用模型定义了应用如何被安全和完全地安装.更新.版本控制和移除.它管理了应用生命周期 - 应用 ...

  5. java并发:同步容器&并发容器

    第一节 同步容器.并发容器 1.简述同步容器与并发容器 在Java并发编程中,经常听到同步容器.并发容器之说,那什么是同步容器与并发容器呢?同步容器可以简单地理解为通过synchronized来实现同 ...

  6. 项目分享五:H5图片压缩与上传

    一.简介 图片的压缩与上传,是APP里一个很常用的功能.我们来年看 ChiTuStore 是怎样做的.相关文件 App/Module/User/UserInfo.html,App/Module/Use ...

  7. Oracle中修改表名遇到“ORA-00054: 资源正忙, 但指定以 NOWAIT 方式获取资源, 或者超时失效”

    Oracle 11g中想修改表名: rename ASSETPORJECT to ASSETPROJECT; 结果提示:ORA-00054: 资源正忙, 但指定以 NOWAIT 方式获取资源, 或者超 ...

  8. WinForm程序执行JS代码的多种方法以及使用WebBrowser与JS交互

    方法一 使用微软官方组件Interop.MSScriptControl 1.msscript.ocx下载的地址   http://www.microsoft.com/downloads/details ...

  9. Android开发之ViewPager做新手引导界面

    先看一下我们要开发的界面(三张图片,滑到最后一个会出现开始体验的Button,下面的小红点会跟着一起滑动): 首先看一下布局文件: <?xml version="1.0" e ...

  10. android定时器

    Handler+Timer+TimerTask 三.采用Handler与timer及TimerTask结合的方法. 1.定义定时器.定时器任务及Handler句柄 private final Time ...