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)是 ...
随机推荐
- 《细细品味Hive》系列课程
Hi,博友: 我是解耀伟,笔名是虾皮,最近我在极客学院录制Hive系列教程,也是督促自己学习一种方式,可以把自己的学习积累有方向,星期天也能做点有意义的事情.在做每一期的过程中,需要找资料,总结,先自 ...
- 跟我学习Storm_Storm基本概念
首先我们通过一个Storm和Hadoop的对比来了解Storm中的基本概念. 接下来我们再来具体看一下这些概念. Nimbus:负责资源分配和任务调度. Supervisor:负责接受nimbus分配 ...
- lecture16-联合模型、分层坐标系、超参数优化及本课未来的探讨
这是HInton的第16课,也是最后一课. 一.学习一个图像和标题的联合模型 在这部分,会介绍一些最近的在学习标题和描述图片的特征向量的联合模型上面的工作.在之前的lecture中,介绍了如何从图像中 ...
- Node基础:url查询参数解析之querystring
模块概述 在nodejs中,提供了querystring这个模块,用来做url查询参数的解析,使用非常简单. 模块总共有四个方法,绝大部分时,我们只会用到 .parse(). .stringify() ...
- CI(CodeIgniter)框架入门教程——第二课 初始MVC
本文转载自:http://www.softeng.cn/?p=53 今天的主要内容是,使用CodeIgniter框架完整的MVC内容来做一个简单的计算器,通过这个计算器,让大家能够体会到我在第一节课中 ...
- 2015/11/9用Python写游戏,pygame入门(8):按钮和游戏结束
昨天没有更新内容,今天相对多写一些. 因为我们已经基本完成游戏框架,但是游戏结束后,并不知道怎样比较好开始.我本来本着懒的原则,想结束后显示一个黑屏,然后你重新点一下鼠标就重新开始.但是那样实在太不像 ...
- IIS W3SVC 无法启动1068错误的解决
苦苦寻找解决方法多天之后,终于看到了最简单的处理方法. 故障: 试遍网上各种方法,司马当活马,CMD下输入如下命令,然后重启: fsutil resource setautoreset true C: ...
- 转一篇Unity客户端与Java服务器的通信
转自:http://www.programering.com/a/MTNxYDMwATQ.html A few days ago a friend asked me about Unity3D ins ...
- Android之Activity启动模式
正常模式 每个应用都有一个任务栈,任务栈中保存着已创建的Activity,先创建的Activity先入栈,栈顶是当前正在显示的activity(running),这是正常模式下的Activity的管理 ...
- Java Little Knowledge
1.Constructor running order of Base class and Derived class This is Alibaba's audition problem. clas ...