文件上传
html中添加表单
1 2 3 4
| <form method="post" enctype="multipart/form-data" action="ProcessUpload.ashx"> <input type="file" name="file1"/> <input type="submit" value="upload"/> </form>
|
文件上传注意点:
- 必须使用
post
- form中
enctype="multipart/form-data"
,使用表单快
- 添加文件域
<input type="file" name="file1"/>
enctype
默认为application。。键值对形式,使用multipart/form-data
后,request报文会生成分割符,将传输的数据进行块分割,以二进制形式发送到服务器
ProcessUpload.ashx中处理上传的文件
1 2 3 4
| var file = context.Request.Files[0]; string filename = Path.GetFileName(file.FileName); string saveFilename = Guid.NewGuid().ToString() + "_" + filename; file.SaveAs(context.Server.MapPath("upload/" + saveFilename));
|
context.Request.Files[0]
获取上传的第一个文件
string filename = Path.GetFileName(file.FileName)
因为上传时文件名为绝对路径
string saveFilename = Guid.NewGuid().ToString() + "_" + filename;
保存文件的名字采用Guid加上原文件名字。
file.SaveAs(context.Server.MapPath("upload/" + saveFilename));
SaveAs中使用的是绝对路径,所以可以将上传的文件放入任意地方!
此次我上传的是style.css,保存在\upload\689ea264-84b0-4124-989e-998f0ecb12e4_style.css下
大量数据存储解决方法
当碰到大量图片等数据时,放在一个文件夹显然不合适,这时候应该拆分为多层文件夹,将文件名与对应的位置信息存储在数据库中
解决方法,可以取每次上传文件的hashcode
(共32位)与0xf(1111)
做&运算得到0-15之间的一个数作为第一层文件夹的名字,第二层分层将hashcode
右移四位再做与,为下一层目录,。。一共可以产生16^8次方个文件夹
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/plain"; if (context.Request.Files.Count == 0) { context.Response.Write("failed"); context.Response.End(); } var file = context.Request.Files[0]; string filename = System.IO.Path.GetFileName(file.FileName);
string dir1 = (file.GetHashCode() & 0xF).ToString(); string dir2 = (file.GetHashCode() >> 4 & 0xF).ToString(); System.IO.Directory.CreateDirectory(context.Server.MapPath("upload") + "/" + dir1 + "/" + dir2);
file.SaveAs(context.Server.MapPath("Upload") + "/" + dir1 + "/" + dir2 + "/" + Guid.NewGuid() + filename);
context.Response.Write("success"); }
|
文件下载
html:
1 2 3 4 5 6 7 8 9 10 11
| <body> <p> <a href="ProcessDownload.ashx?id=BackButton.jpg">BackButton.jpg</a> </p> <p> <a href="ProcessDownload.ashx?id=Computer.png">Computer.png</a> </p> <p> <a href="ProcessDownload.ashx?id=Credentials_ENU.xml">Credentials_ENU.xml</a> </p> </body>
|
ashx:
1 2 3 4 5 6 7
| public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/plain" string filename = context.Request["id"] context.Response.AddHeader("Content-Disposition", "attachment;filename=" + "\"" + HttpUtility.UrlDecode(filename) + "\"") context.Response.WriteFile("Download/" + filename) }
|
context.Response.AddHeader("Content-Disposition", "attachment;filename=" + "\"" + HttpUtility.UrlDecode(filename) + "\"");
添加回复报文头 :这是一个附件不用解析,同时文件名使用HttpUtility.UrlDecode(filename)
是将中文转换成 对应的编码,防止乱码
context.Response.WriteFile("Download/" + filename);
将文件以二进制直接返回