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&txtEmail=138@163.com&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");//输出文件内容,文件路径