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)是 ...
随机推荐
- React Native开发技术周报2
(1).资讯 1.React Native 0.22_rc版本发布 添加了热自动重载功能 (2).技术文章 1.用 React Native 设计的第一个 iOS 应用 我们想为用户设计一款移动端的应 ...
- ubuntu14.04禁用guest用户登录
打开终端(ctrl+alt+t) sudo echo -e "[SeatDefaults]\nallow-guest=false" > /usr/share/lightd ...
- [转]Android中Xposed框架篇—利用Xposed框架实现拦截系统方法
一.前言 关于Xposed框架相信大家应该不陌生了,他是Android中Hook技术的一个著名的框架,还有一个框架是CydiaSubstrate,但是这个框架是收费的,而且个人觉得不怎么好用,而Xpo ...
- 采访ServiceStack的项目领导Demis Bellot——第1部分(网摘)
ServiceStack是一个开源的.支持.NET与Mono平台的REST Web Services框架.InfoQ有幸与Demis Bellot深入地讨论了这个项目.在这篇两部分报道的第1部分中,我 ...
- mac下CornerstoneSVN出错 Description : The working copy is locked due to a previous error
使用CornerStone工具update最新SVN代码报错:The working copy is locked due to a previous error,不仅无法上传,也无法更新,错误提示被 ...
- JSON返回DateTime/Date('123123123')/解决办法
Date.prototype.format = function (format) //author: meizz { var o = { "M+& ...
- python 英文字串首字母改为大写
#英文字串首字母改为大写 st = "string" St = st[0].upper() + st[1:] 2016-10-22 后来了解到 python 内部有相关实现,感觉 ...
- 【JavaEE企业应用学习记录】验证配置
package sanglp; import com.opensymphony.xwork2.ActionSupport; import com.opensymphony.xwork2.validat ...
- java虚拟机和Dalvik虚拟机的区别
java虚拟机和Dalvik虚拟机的区别: java虚拟机Dalvik虚拟机 java虚拟机基于栈. 基于栈的机器必须使用指令来载入和操作栈上数据,所需指令更多更多dalvik虚拟机是基于寄存器的 j ...
- Android布局方式_RelativeLayout
RelativeLayout(相对布局)允许子元素指定它们相对于其他元素或父元素的位置(通过ID指定),因此用户可以右对齐,或上下对齐,或置于屏幕中央的形式来排列两个元素. RelativeLayou ...