服务器端检查两种方式:
1.检查文件的扩展名.
2.读取文件的二进制.
检查文件的扩展名:
检查文件的扩展名: //判断是否有上传文件 if (FileUpload1.HasFile) { //截取要上传文件的扩展名 //string extension = FileUpload1.FileName .Substring(FileUpload1.FileName.LastIndexOf(".")).ToLower(); string extension = System.IO.Path .GetExtension(FileUpload1.FileName).ToLower(); //上传文件是否大于10MB if (FileUpload1.PostedFile.ContentLength < 10485760) { //设置支持上传的文件格式 string[] allowedextension = { ".jpg", ".gif", ".jpeg", ".bmp", ".png" }; for (int i = 0; i < allowedextension.Length; i++) { //判断上传文件扩展名是否正确 if (!(extension != allowedextension[i])) { try { //上传文件 FileUpload1.PostedFile.SaveAs(Server.MapPath("~/Files/")+ FileUpload1.FileName); lblMessage.Text = "文件上传成功!"; break; } catch (Exception ex) { lblMessage.Text = "出现错误,无法上传!"; } } else { lblMessage.Text = "不支持" + extension + "格式的文件!"; } } } else { lblMessage.Text = "上传文件大小不能超过10MB!"; } } else { lblMessage.Text = "不存在上传文件!"; }
以上例子做法的弊端,假设上传文件是.wma文件,把扩展名改成.jpg文件那么将不能被识别,依然能够上传.
解决方法:通过读取文件的二进制,每种文件的二进制前面两个字节都是不一样的,不同的文件扩展名它的
二进制前面两个字节是不同的.我们可以通过这种方式来检测文件的扩展名.如:.jpg文件前两个字节是:255216
.gif文件前两个字节是:7173,6677是BMP,13780是PNG;7790是exe,8297是rar.
上传文件名相同,文件将被覆盖,我们要对文件名的唯一性处理该怎么办呢?
上传文件名唯一性的处理:
1.利用时间戳
2.利用GUID(全局统一标识符)
GUID的介绍可以参考;http://jhxk.iteye.com/admin/blogs/393195
读取文件的二进制并且对文件名的唯一性做处理:
protected void btnUpLoad_Click(object sender, EventArgs e) { if (FileUpload1.HasFile) { //判断文件大小是否大于10MB if (FileUpload1.PostedFile.ContentLength < 10485760) { if (CheckFileType()) { try { /*使用时间戳精确到毫秒,SessionID,上传文件大小, 5位随机数,来做上传文件名唯一性的处理*/ /* Random rd = new Random(); String fileName = DateTime.Now.ToString("yyyyMMddhhmmssfff")+ rd.Next(10000,99999)+ Session.SessionID + FileUpload1.PostedFile.ContentLength + System.IO.Path.GetExtension(FileUpload1.FileName);*/ /*如果使用时间戳还觉得不够保险,需要绝对唯一 *那么可以使用GUID(全局的唯一标示符):*/ string fileName = Guid.NewGuid().ToString() + System.IO.Path.GetExtension(FileUpload1.FileName); FileUpload1.PostedFile.SaveAs(Server.MapPath("~/Files/") + fileName); lblMessage.Text = "上传文件成功!"; } catch (Exception) { lblMessage.Text = "出现异常无法上传!"; } } else { lblMessage.Text = "不支持此文件格式!"; } } else { lblMessage.Text = "文件大小不能超过10MB"; } } else { lblMessage.Text = "文件不存在,请选择文件!"; } } //通过读取文件二进制的前两个字节判断文件的类型 private bool CheckFileType() { //得到客户端文件的绝对路径 String file=FileUpload1.PostedFile.FileName; //创建文件流. System.IO.FileStream fs = new System.IO.FileStream(file,System.IO.FileMode.Open,System.IO.FileAccess.Read); //创建读取文件二进制的对象 System.IO.BinaryReader br=new System.IO.BinaryReader(fs); string fileType=String.Empty; //读取文件的第一个字节,并将读取位置提升一个字节. fileType = br.ReadByte().ToString(); //读取第二个字节,并将读取位置提升一个字节. fileType += br.ReadByte().ToString(); /*如果不知道文件的二进制前两个字节,可以将它打印出来: * Response.Write(fileBinary); */ //允许上传文件的扩展名 String[] allowtedExtension = {"255216", "7173", "6677"}; //判断是否允许上传的文件类型 foreach (string allowEx in allowtedExtension) { if (!(allowEx != fileType)) { return true; } } return false; }
文件下载示例:
//加载下载列表 protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { //首先,获取存放文件目录 string directoryPath = Server.MapPath("~/Files"); //创建目录对象,用来创建,移动和枚举目录及子目录. System.IO.DirectoryInfo dir = new System.IO.DirectoryInfo(directoryPath); /*获取在这个目录下所有的文件, GetFileSystemInfos()方法返回所有文件和子目录*/ System.IO.FileSystemInfo[] infos = dir.GetFileSystemInfos(); //定义列表选项 ListItem myItem; //通过foreach遍历整个文件夹里,所有的文件. foreach (System.IO.FileSystemInfo myfile in infos) { //实例化列表选项 myItem = new ListItem(); //获取文件夹中文件的名称. myItem.Text = myfile.Name; //获取文件夹中文件的完整路径名称. myItem.Value = myfile.FullName; //将里表项添加到列表框中 ListBox1.Items.Add(myItem); } } } //单击下载 protected void btnDownLoad_Click(object sender, EventArgs e) { //获取文件的路径名 String selectName = ListBox1.SelectedItem.Value; //获取文件名 String saveFileName = ListBox1.SelectedItem.Text; //用来创建,复制,移动,打开文件的实例 System.IO.FileInfo finfo = new System.IO.FileInfo(selectName); //得到下载文件大小 String fileSize=finfo.Length.ToString(); //首先清空输出流 Response.Clear(); //设置输出流字符集(编码)为UTF-8 Response.Charset = "UTF-8"; Response.ContentEncoding = System.Text.Encoding.UTF8; //设置为缓冲输出,处理完整个响应之后发送它 Response.Buffer = true; //实现动态生成下载的文件名,并进行URL字符串编码,否则文件名为中文会乱码 Response.AppendHeader("Content-Disposition", "attachment;filename=" +HttpUtility.UrlEncode(saveFileName)); //设置HTTP MIME类型(输出流的文件类型) //我们使用未知类型,对它的类型不加以限定. Response.ContentType = "application/unknow"; //不指明Content-Length用Flush的话不会显示下载进度 Response.AddHeader("Content-Length", fileSize); //将指定文件直接写入HTTP响应输出流 Response.WriteFile(selectName); //清空缓冲区,向客户端发出所有缓冲输出 Response.Flush(); Response.Close(); Response.End(); }
下载示例界面参考: