1.上传到服务器的文件不能重名。采用guid_文件原始名称的方式来保存,避免重名。
2.解决大量文件保存在同一个目录下的问题,通过目录分离算法来保证在不同的图片保存在不同的目录下。
全部代码如下:
//通过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");//输出文件内容,文件路径