文件上传和下载

1.上传到服务器的文件不能重名。采用guid_文件原始名称的方式来保存,避免重名。

//通过guid+旧文件名,计算得到一个新的文件名
                        string new_fileName = Guid.NewGuid().ToString() + "_" + Path.GetFileName(fileData.FileName);


2.解决大量文件保存在同一个目录下的问题,通过目录分离算法来保证在不同的图片保存在不同的目录下。

//获取当前new_fileName的哈希码,就是一个整数。
                        int hash_code = new_fileName.GetHashCode();
                        //2.使用该整数和二进制值"1111"(也就是16进制值:0xf)与,获取当前整数的最后4为值。 
                        int dir1 = hash_code & 0xf;//第一层目录
                        //任何类都是继承自object类。object类中有一个方法GetHashCode(),获取当前对象的哈希码。
                        //将原始的hash_code值向右移动4位。、
                        hash_code = hash_code >> 4;
                        int dir2 = hash_code & 0xf;//得到了第二层目录

                        //一共八层,建议封装成一个方法,在此只写到第二层

                        //路径拼接
                        string targetFilePath = Path.Combine(context.Request.MapPath("upload/"), dir1.ToString(), dir2.ToString());
                        //判断当前文件夹是否存在,如果不存在则创建文件夹
                        if (!Directory.Exists(targetFilePath))
                        {
                            Directory.CreateDirectory(targetFilePath);
                        }
                        //2.将用户上传的文件另存为到服务器的目录下。
                        //将文件名与目录拼接。
                        targetFilePath = Path.Combine(targetFilePath, new_fileName);


3.判断用户上传的是否是图片,只允许上传图片。

if ((ext == ".jpg" || ext == ".jpeg" || ext == ".png" || ext == ".gif" || ext == ".bmp") && fileData.ContentType.ToLower().StartsWith("image"))
                    {}

全部代码如下:

public class ProcessUpload : IHttpHandler
    {

        public void ProcessRequest(HttpContext context)
        {
            context.Response.ContentType = "text/plain";
            //1.获取用户上传的文件
            if (context.Request.Files.Count > 0)
            {
                //获取第一个文件域中上传上来的文件
                HttpPostedFile fileData = context.Request.Files[0];

                //判断上传上来的文件字节数是否大于0
                if (fileData.ContentLength > 0)
                {
                    string ext = Path.GetExtension(fileData.FileName);

                    if ((ext == ".jpg" || ext == ".jpeg" || ext == ".png" || ext == ".gif" || ext == ".bmp") && fileData.ContentType.ToLower().StartsWith("image"))
                    {
                        #region 计算文件名称和目录,保存文件

                        //通过guid+旧文件名,计算得到一个新的文件名
                        string new_fileName = Guid.NewGuid().ToString() + "_" + Path.GetFileName(fileData.FileName);


                        //获取当前new_fileName的哈希码,就是一个整数。
                        int hash_code = new_fileName.GetHashCode();
                        //2.使用该整数和二进制值"1111"(也就是16进制值:0xf)与,获取当前整数的最后4为值。 
                        int dir1 = hash_code & 0xf;//第一层目录
                        //任何类都是继承自object类。object类中有一个方法GetHashCode(),获取当前对象的哈希码。
                        //将原始的hash_code值向右移动4位。、
                        hash_code = hash_code >> 4;
                        int dir2 = hash_code & 0xf;//得到了第二层目录

                        //一共八层,建议封装成一个方法,在此只写到第二层

                        //路径拼接
                        string targetFilePath = Path.Combine(context.Request.MapPath("upload/"), dir1.ToString(), dir2.ToString());
                        //判断当前文件夹是否存在,如果不存在则创建文件夹
                        if (!Directory.Exists(targetFilePath))
                        {
                            Directory.CreateDirectory(targetFilePath);
                        }
                        //2.将用户上传的文件另存为到服务器的目录下。
                        //将文件名与目录拼接。
                        targetFilePath = Path.Combine(targetFilePath, new_fileName);
                        fileData.SaveAs(targetFilePath);

                        #endregion

                        context.Response.Write("文件上传成功!");
                    }
                    else
                    {
                        context.Response.Write("非法的文件!");
                    }
                }
            }
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }


前端代码

<!-------  上传文件------------->
    <!-- 
    1.上传客户端表单需要注意的:
    1>表单的提交方式,必须为post。method="post"
    2>必须修改表中提交数据时的数据组织方式,设置enctype,enctype="multipart/form-data"
    默认情况下,表单的enctype设置如下:enctype="application/x-www-form-urlencoded"。设置完毕该项后,其实最终是设置到了请求报文头的Content-Type中,这种设置,表单中最终数据的组织方式是,类似于下面的这种方式:txtName=%E9%9A%9C%E7%A2%8D%E6%98%AF%E5%93%AA%E4%B8%AA&txtPhone=13888888888&[email protected]&selGroups=3
    //当设置enctype="multipart/form-data",时,数据提交方式,是以分割线的方式来组织的。

    3>表单中需要有一个文件域。
    -->
    <form action="ProcessUpload.ashx" method="post" enctype="multipart/form-data">
    
    <p>
        请选择要上传的文件:<input id="fileData" type="file" name="fileData" value="" />
    </p>
    <input id="btnSubmit" type="submit" value="提交" />
    </form>



文件下载

只需设置response的Content-Disposition值,让浏览器知道这是下载文件即可。

	string encodeFileName = HttpUtility.UrlEncode("aa.txt");//国际通用防止产生乱码。生成ASCII
        context.Response.AddHeader("Content-Disposition", string.Format("attachment;filename=\"{0}\"", encodeFileName));//在响应头中加上Content-Disposition,attachment表示以附件形式下载.
        context.Response.WriteFile("aa.txt");//输出文件内容,文件路径




猜你喜欢

转载自blog.csdn.net/mkcrawling/article/details/50328025