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)是 ...
随机推荐
- Java7并发编程实战(一) 线程的等待
试想一个情景,有两个线程同时工作,还有主线程,一个线程负责初始化网络,一个线程负责初始化资源,然后需要两个线程都执行完毕后,才能执行主线程 首先创建一个初始化资源的线程 public class Da ...
- 读书摘要,Hackable Projects
完整读完Google的三篇谈Hackable Projects的文章,以及一篇从Test Pyramid看UnitTest的比重.一篇谈Optimal Logging的文章,感觉这5篇在测试.日志两个 ...
- c++ 指针(一)
指针:是说指针名表示的是地址.是一个变量,存储的是值的地址,而不是值本身 *运算符被称为间接值或解除引用运算符也可以叫做取地址符 声明一个指针 int * p_data; * p_data的类型为in ...
- 浅析手机抓包方法实践(zt)
原文:http://drops.wooyun.org/tips/12467 0x00 摘要 在移动逆向分析以及 App 开发的时候,总会需要对其网络行为进行监控测试,本文总结一些抓包思路,并对其使用方 ...
- Bootstrap系列 -- 4. 文本内容强调
一. 文本强调基本样式 .text-muted:提示,使用浅灰色(#999) .text-primary:主要,使用蓝色(#428bca) .text-success:成功,使用浅绿色(#3c763d ...
- [BZOJ2876][NOI2012]骑行川藏(拉格朗日乘数法)
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=2876 分析:就是要求约束条件下函数的极值,于是拉格朗日乘数列方程,发现化简后的关于vi ...
- 使用socket()函数创建套接字
在Linux中,一切都是文件,除了文本文件.源文件.二进制文件等,一个硬件设备也可以被映射为一个虚拟的文件,称为设备文件.例如,stdin 称为标准输入文件,它对应的硬件设备一般是键盘,stdout ...
- linux初级,连网
第一次写,今天刚好装上centos,然后就玩装一些软件,但要联网,所以琢磨了半天连网,下面总结下今天积累的一些知识点吧! 首先需要查看电脑有没有装驱动:ifconfig -a, 看有没有eh0(网卡) ...
- js中如何去获取外部css样式
<!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>& ...
- 一个Activity掌握Android5.0新控件 (转)
原文地址:http://blog.csdn.net/lavor_zl/article/details/51279386 谷歌在推出Android5.0的同时推出了一些新控件,Android5.0中最常 ...