检查图片是否存在,这个功能用的非常广,比如说百度网盘、迅雷等APP,你以为它真的能秒传?你以为你上传的文件是唯一的?呵呵!可能吧…
逻辑:
比如别人要发馒头,首先得找到要发馒头的地点,然后召集需要馒头的小朋友…人手一个,发馒头的要用眼观察or问小朋友,你有馒头吗?没有,OK,我给你一个馒头。哦我有了哦,既然有了就不给你发了…这时候你可以叫需要馒头的小朋友排成多条队,然后把另一个or几个随行的分配给每条队帮忙发馒头,这样就会节省不少时间…
代码实现:
public string save_the_image(HttpPostedFileBase fileimage) { MD5 md5 = new MD5CryptoServiceProvider(); string filename = ""; bool Count = false; if (fileimage != null) { byte[] UserFile = new byte[fileimage.ContentLength]; fileimage.InputStream.Read(UserFile, 0, fileimage.ContentLength); if (Directory.Exists(Server.MapPath("~/UploadingImage")) == false)//是否存在 UploadingImage 文件夹,则创建 { Directory.CreateDirectory(Server.MapPath("~/UploadingImage")); } DirectoryInfo GetFolder = new DirectoryInfo(Server.MapPath("~/UploadingImage"));//获取文件夹 FileInfo[] file = GetFolder.GetFiles();//获取文件夹下文件 //循环全部图片,是否存在 foreach (var f in file) { //取MD5值 byte[] retval = md5.ComputeHash(UserFile); StringBuilder sc = new StringBuilder(); for (int i = 0; i < retval.Length; i++) { sc.Append(retval[i].ToString("x2")); } string FullNameMD5 = GetMD5(f.FullName); string scMD5 = sc.ToString(); if (FullNameMD5.Equals(scMD5)) { filename = f.Name; Count = true; break; } } if (Count == false) { //拼接文件名,文件夹图片数量+1加上后缀名 fileimage.SaveAs(Server.MapPath("~/UploadingImage/") + (file.Length + 1) + Path.GetExtension(fileimage.FileName));//保存文件到服务器 filename = (file.Length + 1) + Path.GetExtension(fileimage.FileName); } } return filename; } /// <summary> /// 取MD5 /// </summary> /// <param name="s"></param> /// <returns></returns> static string GetMD5(string s) { FileStream file = new FileStream(s, FileMode.Open); MD5 md5 = new MD5CryptoServiceProvider(); byte[] retval = md5.ComputeHash(file); file.Close(); StringBuilder sc = new StringBuilder(); for (int i = 0; i < retval.Length; i++) { sc.Append(retval[i].ToString("x2")); } Console.WriteLine("文件MD5:{0}", sc); return sc.ToString(); }
参数
获取到用户上传的文件
HttpPostedFileBase fileimage
变量
MD5 md5 = new MD5CryptoServiceProvider(); 实例化MD5实体类 string filename = ""; 需要返回唯一的参数,用于拼接文件路径保存数据库 bool Count = false; 用于判断是否已找到相同图片
核心代码
if (fileimage != null){...} 用于判断是否有上传文件
读取上传的文件
byte[] UserFile = new byte[fileimage.ContentLength]; fileimage.InputStream.Read(UserFile, 0, fileimage.ContentLength); 判断服务器是否存在该文件夹(Server.MapPath获取源文件位置上的某个位置) if (Directory.Exists(Server.MapPath("~/UploadingImage")) == false)、 { 不存在该文件夹,在源文件目录上创建它 Directory.CreateDirectory(Server.MapPath("~/UploadingImage")); } 获取源文件目录上的文件夹 DirectoryInfo GetFolder = new DirectoryInfo(Server.MapPath("~/UploadingImage")); 读取文件夹下的文件 FileInfo[] file = GetFolder.GetFiles();
(获取该目录图片)
获取出来的是个列表,将获取到的文件循环(f是每循环一次获取的对象,file为源对象)
foreach (var f in file) { ... }
将用户图片MD5值取出来(每个文件哈希值并不一样,相同文件除外)
byte[] retval = md5.ComputeHash(UserFile);
因为他们是数组,所以把他们转为字符串
StringBuilder sc = new StringBuilder(); for (int i = 0; i < retval.Length; i++) { sc.Append(retval[i].ToString("x2")); }
获取f的的MD5,这里是另外写了一个方法专门获取MD5,所以上面的获取是多余的
string FullNameMD5 = GetMD5(f.FullName);
string scMD5 = sc.ToString();
判断他们是否相等
if (FullNameMD5.Equals(scMD5)) { 相等的话吧文件名称拿出来赋值给filename 变量 filename = f.Name; 让Count变量为true,因为他是用来判断是否需要把上传的图片保存到服务器,true代表服务器是有这张图 片的,不需要上传,false则没有图片 Count = true; 结束该循环,都找到文件了还循环啥子哦!浪费时间吗?万一有一千万张图片,你需要的图片就在第一张, 你一开始就已经拿到了,难道你还要继续千万次循环? break; }
(寻找图片可开启多线程寻找不知道多线程的自己查,你觉得是你一个人做事快还是多个人做同样一件事快)
你有馒头吗
if (Count == false) {...}
啊我没有馒头,快给我…
保存文件到服务器
fileimage.SaveAs(Server.MapPath("~/UploadingImage/") + (file.Length + 1) + Path.GetExtension(fileimage.FileName));
把完整路径拼接出来
filename = (file.Length + 1) + Path.GetExtension(fileimage.FileName);
返回路径
return filename;
这是封装的那个获取MD5的方法
public static string GetMD5(string s) { FileStream file = new FileStream(s, FileMode.Open); MD5 md5 = new MD5CryptoServiceProvider(); byte[] retval = md5.ComputeHash(file); file.Close(); StringBuilder sc = new StringBuilder(); for (int i = 0; i < retval.Length; i++) { sc.Append(retval[i].ToString("x2")); } Console.WriteLine("文件MD5:{0}", sc); return sc.ToString(); }