asp.net 下载文件Response.TransmitFile(filename)的同时记录文件被下载次数异常
- C# code
protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { try { //Session["userid"] = "adminTest"; //下载文件页面不能用session string userid = ""; userid = Request.QueryString["uid"].ToString().Trim(); string FileGuid = Request.QueryString["id"].ToString().Trim(); Guid guid = new Guid(FileGuid); string FileServerPath = ""; FileServerPath = bllfile.GetFilePath(userid, guid).ServerPath; if (FileServerPath == "") { Response.Write("<font size=3 color=red>没有找到文件!</font>"); } else { if (!SendFile(FileServerPath)) { Response.Write("<font size=3 color=red>下载出错,请与管理员联系!</font>"); } else { int k = 0; k = k + bllfile.Update(guid); //这里是去更新文件下载次数+1,但是文件越大下载的时间越长,这里就会多次执行,为什么,而不是只执行一次 if (k < 1) { Response.Write("<font size=3 color=red>更新您的下载次数失败</font>"); } } } catch (Exception ex) { Common.LogManager.LogWrite("Inner_ResourceList_DownFile-->Page_Load", ex.ToString()); Response.Write("<font size=3 color=red>对不起,无法下载文件!</font>"); } Response.End(); } } private bool SendFile(string filename) { bool check; try { Response.Clear(); Response.ClearHeaders(); FileInfo f = new FileInfo(filename); Response.ContentType = "application/octet-stream"; Response.ContentEncoding = System.Text.Encoding.GetEncoding("gb2312"); Response.AddHeader("Content-Disposition", "attachment;filename=" + Server.UrlPathEncode(f.Name)); Response.TransmitFile(filename); check = true; } catch (Exception ex) { check = false; } return check; }k = k + bllfile.Update(guid); //这里是去更新文件下载次数+1,但是文件越大下载的时间越长,这里就会多次执行,为什么,而不是只执行一次,发现这个page_load里的东西好像是循环碰次执行,导致这一句多次执行。
难道是Response.TransmitFile(filename);导致的向客户发送数据会多次发送?
[解决办法]
Response.AppendHeader("Content-Disposition", "attachment;filename=" + System.Web.HttpUtility.UrlEncode(FileName.Substring(FileName.LastIndexOf('/') + 1), System.Text.Encoding.GetEncoding("utf-8")));
Response.ContentType = "application/octet-stream";
Response.WriteFile("");
Response.End();
[解决办法]
最近也遇到这个问题
直接IE保存下载没得问题 但是用迅雷这类软件就会出现
感觉可能这类软件有重链的情况
我解决的办法是分段下载 只有在最后一段的时候才保存至数据库
同时能解决 用户点取消不载不计算的问题
[解决办法]
貌似就 这个方法 Response.TransmitFile(filename);
TransmitFile MSDN解释,将文件直接输入HTTP 输出流,不进行缓存
也就意味着,文件直接传送到客户端,而不是先缓存好整个文件 传送到客户端
因此如果文件过大,就会导致放松请求,以保持文件的下载
换成 response.writeFile() 试下
[解决办法]
那你可以检测request的头里面有没有Range数据。
如果有range,就不要+1。
详情请看
http://hi.baidu.com/longhtml/blog/item/d4d96000f984f680e850cd04.html
[解决办法]
只是简单用几秒钟看了一下你的代码,没有仔细看。
我想你没有了解过什么是http下载。我不知道ie是否仍然是单线程下载,但就算单线程,当它发现数据流中断的时候,也会重新下载的,再次执行Page_Load。而一些其它的浏览器、下载工具,则完全可能同时开启2个甚至几十个下载线程,然后每一个线程都判断服务器返回的数据流中的信息是否说明了支持断点续传,如果不支持断点续传再放弃除了主线程之外的其它线程。因此下载一个文件开始,服务器可能立刻收到几十个请求(执行几十遍Page_Load)也是完全可能的。
不是说“Response.TransmitFile(filename);导致的向客户发送数据会多次发送”,而是实际应用情况就是复杂的,不是你理解的像书上举的简单例子使用一个“Response.TransmitFile(filename);”就能说明下载的概念的。
[解决办法]
一个很烂的方法:
根据IP来判断. 如果同一个IP在1个小时内下载两次的话. 就算一次.
你下载的文件有上G. 估计他们一天最多也就下两次.
[解决办法]
你的文件下载方式确实写的不怎么样..
我以前写了个记录文件下载是否成功的功能. .
- C# code
public class FileInforMation{ private FileInfo _objFile; private DownLoadState _downloadState; public FileInforMation(string path) { _objFile = new FileInfo(path); } /// <summary> /// 文件是否存在 /// </summary> public bool Exists { get { return this._objFile.Exists; } } /// <summary> /// 文件全名 /// </summary> public string FullName { get { return this._objFile.FullName; } } public DateTime LastWriteTimeUTC { get { return this._objFile.LastWriteTimeUtc; } } public long Length { get { return this._objFile.Length; } } public string ContentType { get { return "application/x-zip-compressed"; } } public string EntityTag { get { return "MyExampleFileID"; } } public DownLoadState State { get { return this._downloadState; } set { this._downloadState = value; Save(value); } } /// <summary> /// /// </summary> private void Save(DownLoadState state) { FileStream file = File.Create(HttpContext.Current.Server.MapPath("~/"+state+".txt")); file.Flush(); file.Close(); } }/// <summary>/// 下载状态/// </summary>[Flags]public enum DownLoadState{ /// <summary> /// 下载中.. /// </summary> DownLoading = 1, /// <summary> /// 下载中断 /// </summary> DownloadCancel =2, /// <summary> /// 下载成功 /// </summary> DownloadSucceed = 3}