C#实体图片下载与批量下载(自动保存功能)
新工作,第一个小任务,制作一个点击下载图片的功能。并提供批量下载操作。图片是字节流的形式,存放在数据库中的。
为了避免直接从数据库中,下载失败,会在本地保存一份。
进行压缩的是SharpZip这个压缩帮助类。
首先,创建一个实体,用来存放字节流这些
public class ATLRLAttachment
{
/// <summary>
/// 字节流
/// </summary>
public byte[] FileContent { get; set; } /// <summary>
/// 类型
/// </summary>
public string FileExt { get; set; } /// <summary>
/// 名称
/// </summary>
public string FileName { get; set; }
}
主要是针对这个实体,进行的字节流和名称的读取。因为要自动保存,而且这个功能是可选的,所以我用一个枚举来控制,是否可以执行这个方法。
定义枚举如下:
/// <summary>
/// 是否自动保存
/// add by chenxy 16.3.10
/// </summary>
public enum IsSaveImage
{
Save = ,
NotSave =
}
我是本地机进行的测试,所以字节流模拟工作是从图片进行转换的。那么加上这个图片转换方法。
/// <summary>
/// 通过图片地址将图片转换成字节流
/// add by chenxy 16.3.10
/// </summary>
/// <param name="url">图片地址</param>
/// <returns>字节流</returns>
public byte[] GetImageByte(string url)
{
FileStream fs = new FileStream(url, FileMode.Open);
byte[] byData = new byte[fs.Length];
fs.Read(byData, , byData.Length);
fs.Close();
return byData;
}
打开图片,进行缓冲区,然后把字节流返回。比较懒,没做异常处理。
接下来,是临时保存功能。
/// <summary>
/// 图片临时保存功能
/// add by chenxy 16.3.10
/// <param name="saveByte">字节流</param>
/// <param name="strName">图片名称</param>
/// <param name="strExt">图片后缀</param>
/// <returns>文件路径</returns>
/// </summary>
public string SaveImage(byte[] saveByte, string strName, string strExt)
{
string path = AppDomain.CurrentDomain.BaseDirectory;
string url = string.Format(@"{0}TemporaryImage", path);
path = string.Format(@"{0}\\{1}", url, strName);
//判断目录
if (!Directory.Exists(url))
{
Directory.CreateDirectory(url);
}
//判断文件
if (File.Exists(path))
{
File.Delete(path);
}
MemoryStream fs = new MemoryStream(saveByte);
Image img = Image.FromStream(fs);
ImageFormat imgFormat = ImageFormat.Jpeg;
switch (strExt)
{
case ".bmp":
imgFormat = ImageFormat.Bmp;
break;
case ".png":
imgFormat = ImageFormat.Png;
break;
case ".gif":
imgFormat = ImageFormat.Gif;
break;
}
img.Save(path, imgFormat);
return path;
}
Directory 操作目录,File 操作文件,然后用Image进行最后的保存图片。
然后是单个下载功能代码
public void ImageDown(HttpContext context, ATLRLAttachment model, IsSaveImage save)
{
#region 验证方法
if (model.FileContent == null || model.FileContent.Length < )
{
ErrorMessage(context, "下载链接中没有对应的图片");
return;
}
#endregion
#region 是否临时保存
if (save == IsSaveImage.Save)
{
string strUrl = SaveImage(model.FileContent, model.FileName);
model.FileContent = GetImageByte(strUrl);
}
#endregion
context.Response.AddHeader("Content-Disposition", string.Format("attachment;filename={0}", model.FileName));
context.Response.ContentType = string.Format("image/{0}", model.FileExt.Replace(".", ""));
context.Response.BinaryWrite(model.FileContent);
context.Response.Flush();
context.Response.Close();
}
其中ErrorMessage 是提示信息。
public void ErrorMessage(HttpContext context, string strMsg)
{
context.Response.Write(string.Format("<script language=javascript>alert('{0}');</" + "script>", strMsg));
context.Response.Write("<script language=javascript>history.go(-1);</script>");
context.Response.End();
}
批量下载使用的重载,通过传递IEnumerable 进行批量压缩。
/// <summary>
/// 批量下载
/// add by chenxy 16.3.10
/// </summary>
/// <param name="context">HTTP请求</param>
/// <param name="models">下载集合</param>
public void ImageDown(HttpContext context, IEnumerable<ATLRLAttachment> models, IsSaveImage save)
{
string FileToZip = DateTime.Now.ToString("yyyymmdd") + ".zip";
string path = AppDomain.CurrentDomain.BaseDirectory;
string url = string.Format(@"{0}TemporaryImage", path);
path = string.Format(@"{0}\\{1}", url, FileToZip);
BatchDeleteZip(url);
using (FileStream ms = File.Create(path))
{
using (ZipOutputStream zip = new ZipOutputStream(ms))
{
zip.SetLevel();
int itFileNameNum = ;
foreach (ATLRLAttachment m in models)
{
#region 修改重名文件
if (models.Where(p => p.FileName == m.FileName).Count() > )
{
itFileNameNum++;
try
{
m.FileName = m.FileName.Insert(m.FileName.IndexOf("."), string.Format("_{0}", itFileNameNum));
}
catch (ArgumentNullException)
{
ErrorMessage(context, string.Format("文件名:{0},格式错误,未包含后缀连接符.", m.FileName));
return;
}
}
#endregion
#region 是否临时保存
if (save == IsSaveImage.Save)
{
string strUrl = SaveImage(m.FileContent, m.FileName, m.FileExt);
m.FileContent = GetImageByte(strUrl);
//判断文件
if (File.Exists(strUrl))
{
File.Delete(strUrl);
}
}
#endregion
//如果没有图片就跳过
if (m.FileContent == null || m.FileContent.Length < )
{
continue;
}
ZipEntry entry = new ZipEntry(m.FileName);
zip.PutNextEntry(entry);
zip.Write(m.FileContent, , m.FileContent.Length);
}
zip.Finish();
zip.Close();
}
}
FileInfo fileInfo = new FileInfo(path);
context.Response.Clear();
context.Response.ClearContent();
context.Response.ClearHeaders();
context.Response.AddHeader("Content-Disposition", string.Format("attachment;filename={0}.zip", DateTime.Now.ToString("yyyyMMdd")));
context.Response.AddHeader("Content-Length", fileInfo.Length.ToString());
context.Response.AddHeader("Content-Transfer-Encoding", "binary");
context.Response.ContentType = "application/octet-stream";
context.Response.ContentEncoding = System.Text.Encoding.GetEncoding("utf-8");
context.Response.WriteFile(fileInfo.FullName);
context.Response.Flush();
context.Response.End();
}
批量下载需要删除文件夹,有一个遍历目录并删除文件的方法
/// <summary>
/// 批量删除压缩包
/// add by chenxy 16.3.15
/// </summary>
/// <param name="strUrl">压缩包路径</param>
public void BatchDeleteZip(string strUrl)
{
//判断路径是否为空
if (string.IsNullOrEmpty(strUrl))
{
throw new ArgumentNullException("文件目录为空");
}
//判断是否有目录
if (!Directory.Exists(strUrl))
{
return;
}
//获取目录下所有文件
string[] strFiles = Directory.GetFiles(strUrl);
//判断文件时间长短
foreach (string strfile in strFiles)
{
FileInfo info = new FileInfo(strfile);
if (info.CreationTime.DistanceToday() >= )
{
File.Delete(info.FullName);
} }
}
最后就没的说了,就是普通的调用测试,写的比较乱,勉强能看懂
public void ProcessRequest(HttpContext context)
{
// string path = AppDomain.CurrentDomain.BaseDirectory;
//byte[] result = GetImageByte(string.Format(@"{0}0.jpg", path));
//path = SaveImage(result,"0.jpg");
//result = GetImageByte(path); byte[] result = GetImageByte(@"D://111.jpg");
ImageDown(context, new ATLRLAttachment { FileContent = result, FileExt = ".jpg", FileName = "ce.jpg" }, IsSaveImage.Save);
// File.Delete(path);
return;
//ImageDown(context, result, "imageName.jpg", "jpg"); var list = new[] { new ATLRLAttachment { FileContent = result, FileExt = ".jpg", FileName = "Name.jpg" }, new ATLRLAttachment { FileContent = result, FileExt = ".jpg", FileName = "Name.jpg" } };
ImageDown(context, list, IsSaveImage.Save);
return; }
程序员最有利的武器,就是谷歌,百度。做这个的时候,我就想,用IO流进行保存。但是忘记方法名了,就一直尴尬。
下载地址:https://coding.net/u/chenxygx/p/CodeSave/git/blob/master/Handler1.ashx.cs
记录一下,免得以后再去百度了。By~
C#实体图片下载与批量下载(自动保存功能)的更多相关文章
- 用汇编语言给XP记事本添加“自动保存”功能 good
[文章标题]: 用汇编语言给XP记事本添加“自动保存”功能 [文章作者]: newjueqi [作者邮箱]:zengjiansheng1@126.com [作者QQ]:190678908 [使用工具] ...
- PyCharm 去掉自动保存功能
PyCharm 4.5.4 环境配置 1.去掉"自动保存功能" pycharm默认是自动保存的,习惯自己按 ctrl + s 的可以进行如下设置: 菜单File -> Set ...
- 第四十一篇-android studio 关闭自动保存功能
此方法不可用. 第一步:取消自动保存功能 File > Settings > Appearance & Behavior > System Settings > Syn ...
- Intellij IDEA 开启自动保存功能
IntelljJ IDEA关于文件自动保存功能主要有两种方式: 切换到其他应用时保存变化(默认使能) 设置路径:Settings >> Apperance & Behavior & ...
- 【工具】Sublime Text 自动保存功能
经常需要所以要频繁用到"ctrl+s"保存还是挺麻烦的,所以有的人需要用到失去焦点自动保存功能,这里简单记录下 1.点击"Preferences"里的设置-用户 ...
- WebStorm 编辑器 关闭自动保存功能及添加*星星标记
WebStorm 关闭自动保存功能添加*星星标记为什么要关闭自动保存? 在前端项目工作当中,往往会采用自动化环境(Gulp.webpack等)当文本发生变化的时候就会自动编译代码.在we ...
- 关于vscode自动跳转回车的解决方法(关闭vscode自动保存功能;可能和其他插件有冲突)
关于vscode自动跳转回车的解决方法(关闭vscode自动保存功能:可能和其他插件有冲突)
- 通过HttpURLConnection下载图片到本地--批量下载
一.背景说明 这篇文章讲述的是批量下载附件,在上一篇文章中,介绍了下载单个附件(上一篇文章). 二.实现思路 主要的实现思路:创建文件夹->文件夹中创建需要下载的文件->压缩文件夹-> ...
- JAVA SFTP文件上传、下载及批量下载
JavaJsch 1.jsch官方API查看地址(附件为需要的jar) http://www.jcraft.com/jsch/ 2.jsch简介 JSch(Java Secure Channel)是 ...
随机推荐
- 还记得高中的向量吗?leetcode 335. Self Crossing(判断线段相交)
传统解法 题目来自 leetcode 335. Self Crossing. 题意非常简单,有一个点,一开始位于 (0, 0) 位置,然后有规律地往上,左,下,右方向移动一定的距离,判断是否会相交(s ...
- CodeIgniter框架入门教程——第三课 URL及ajax
本文转载自:http://www.softeng.cn/?p=74 这节课讲一下CI框架的路由规则,以及如何在CI框架下实现ajax功能. 首先,先介绍CI框架的路由规则,因为CI框架是在PHP的基础 ...
- linux svn搭建
1 安装: yum install subversion 2 查看svn安装信息: rpm -ql subversion 3 创建svn根目录: svnserve -d -r /svn 4 进入/sv ...
- 在eclipse中使用第三方库总结
一.建立user library 导入第三方jar文件,最简单的方式是:右键工程/属性/java build path/add external jars. 另一种方式是:window/prefren ...
- Android布局方式_RelativeLayout
RelativeLayout(相对布局)允许子元素指定它们相对于其他元素或父元素的位置(通过ID指定),因此用户可以右对齐,或上下对齐,或置于屏幕中央的形式来排列两个元素. RelativeLayou ...
- Java网络编程——IP
类:InetAdrress 该类主要用于表示互联网协议(IP对象)地址,且无构造方法 主要方法: public static InetAddress getLocalHost()-->返回本地主 ...
- Java网络编程——概述
一.网络模型 OSI七层模型 应用层 表示层 会话层 传输层: 网络层: 链路层 物理层:比特流 TCP/IP四层模型 应用层 传输层:数据包,TCP/UDP 网络层:数据帧 物理层:比特流 二.网络 ...
- js浏览器窗口
一.clientwidth和clientheight 注:返回了元素大小,但没有单位,默认单位是 px,如果你强行设置了单位,比如 100em之类,它还是会返回 px的大小. (CSS获取的话,是照着 ...
- [转]Oracle中使用Rownum分页详细例子
原文地址:http://www.jb51.net/article/52272.htm 在MySQL中,我们通常都使用limit来完成数据集获取的分页操作,而在Oracle数据库中,并没有类似limit ...
- jQuery常用的元素查找方法总结
$("#myELement") 选择id值等于myElement的元素,id值不能重复在文档中只能有一个id值是myElement所以得到的是唯一的元素 $("di ...