`

Asp.Net文件上传之简单文件上传(下)

阅读更多

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

 下载示例界面参考:

 

  • 大小: 7.9 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics