服务器端检查两种方式:
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.javaeye.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();
- }