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)是 ...
随机推荐
- Android -- View移动的六种方法
layout() 如果你将滑动后的目标位置的坐标传递给layout(),这样子就会把view的位置给重新布置了一下,在视觉上就是view的一个滑动的效果. public class DragView ...
- PRML读书会第十三章 Sequential Data(Hidden Markov Models,HMM)
主讲人 张巍 (新浪微博: @张巍_ISCAS) 软件所-张巍<zh3f@qq.com> 19:01:27 我们开始吧,十三章是关于序列数据,现实中很多数据是有前后关系的,例如语音或者DN ...
- C#发展历程以及C#6.0新特性
一.C#发展历程 下图是自己整理列出了C#每次重要更新的时间及增加的新特性,对于了解C#这些年的发展历程,对C#的认识更加全面,是有帮助的. 二.C#6.0新特性 1.字符串插值 (String In ...
- 自己画WinForm 皮肤包括默认控件
好久没来博客园,今天捣鼓到现在就是为了把之前的皮肤控件完善好, 之前也看了很多技术文章,大多数都是自己重写系统控件实现换肤,几乎没有像东日的(IrisSkin)控件一样 添加一个组件 把系统的皮肤全换 ...
- 使textarea支持tab缩进
//textarea支持tab缩进 $("textarea").on( 'keydown', function(e) { if (e.keyCode == 9) { e.preve ...
- Spring学习进阶(四) Spring JDBC
Spring JDBC是Spring所提供的持久层技术.主要目的是降低使用JDBC API的门槛,以一种更直接,更简洁的方式使用JDBC API.在Spring JDBC里用户仅需要做哪些比不可少的事 ...
- webpack 插件: html-webpack-plugin
插件地址:https://www.npmjs.com/package/html-webpack-plugin 这个插件用来简化创建服务于 webpack bundle 的 HTML 文件,尤其是对于在 ...
- parse date receiving from mvc jsonresult
if we received data like this: ,"Date":"\/Date(1410969600000)\/", we can parse i ...
- SharePoint 站点集和子站点数据互相读取
1.站点集中可以使用SPSite.AllWeb,然后遍历所有站点的isRootWeb,根据siteTemplate取得需要的子站点. /// <summary> /// Handles t ...
- Bete冲刺第六阶段
Bete冲刺第六阶段 github:https://github.com/RadioGroup/JourneyHelper 今日工作: web: 陈灿:新增了用户信息更新接口,优化了部分接口逻辑,更新 ...