Stream下载文件取消后再点击下载文件被占用
代码如下:
context.Response.ContentType = "text/plain"; string filePath = context.Request.Params["path"];//文件相对路径 if (FileExists(context.Server.MapPath(filePath))) { // 允许共享 System.IO.Stream input = new System.IO.FileStream(context.Server.MapPath(filePath), System.IO.FileMode.Open, System.IO.FileAccess.ReadWrite, System.IO.FileShare.Inheritable); context.Response.ContentType = "application/octet-stream"; //文件名 string fileName = System.IO.Path.GetFileName(filePath); //文件名编码 string encodingFileName = context.Server.UrlEncode(fileName).Replace('+', ' '); context.Response.AddHeader("Content-Disposition", string.Format("attachment;filename={0}", encodingFileName)); // 输出到 this.Response.OutputStream 中 System.IO.Stream output = context.Response.OutputStream; // 创建一个块缓冲 byte[] buffer = new byte[10 * 1024]; // 手工关闭输出的缓存 context.Response.BufferOutput = false; TransmitFile(input, output, buffer); output.Close(); input.Close(); context.Response.End(); }using System;using System.Collections;using System.Data;using System.Linq;using System.Web;using System.Web.Services;using System.Web.Services.Protocols;using System.Xml.Linq;namespace Asiastar.NR.Ajax{ /// <summary> /// $codebehindclassname$ 的摘要说明 /// </summary> [WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] public class Handler1 : IHttpHandler { public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/plain"; string id = context.Request["id"].ToString();//获取资源的编号 System.IO.Stream iStream = null; byte[] buffer = new Byte[10000]; int length; long dataToRead; NRBLL.File bf = new Asiastar.NRBLL.File(); Guid guid = new Guid(id); if (bf.FN_SerchPathByFileId(guid).Tables[0].Rows[0]["FilePath"] != null)//判断数据库路径是否存在 { string filepath = bf.FN_SerchPathByFileId(guid).Tables[0].Rows[0]["FilePath"].ToString();//获取资源完整路径 D:\资源文件\600cc139-14cf-448e-9e50-daa972d35e01.jpg string Oidfilename = bf.FN_SerchPathByFileId(guid).Tables[0].Rows[0]["FileNam"].ToString();//旧文件名称 //string filename = System.IO.Path.GetFileName(filepath);//获取文件名称+后缀名 600cc139-14cf-448e-9e50-daa972d35e01.JPG //int index = filepath.IndexOf("."); //string filetype = filepath.Substring(index).ToLower();//后缀名 //string newfilename = Oidfilename; //string filepath1 = bf.FN_SerchPathByFileId(guid).Tables[0].Rows[0]["FilePath"].ToString().Substring(0,filepath.Length - 8); try { string fileName = HttpUtility.UrlEncode(System.Text.Encoding.UTF8.GetBytes(Oidfilename));//解码(注意这里2层解码) Oidfilename = Oidfilename.Replace("+", "%20"); //将“+”替换成“空格” iStream = new System.IO.FileStream(filepath, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.Read); dataToRead = iStream.Length; context.Response.ContentType = "application/octet-stream"; context.Response.AddHeader("Content-Disposition", "attachment; filename=" + HttpUtility.UrlEncode(Oidfilename, System.Text.Encoding.UTF8)); //下载的时候下载原来的文件名称 while (dataToRead > 0) { if (context.Response.IsClientConnected) { length = iStream.Read(buffer, 0, 10000); context.Response.OutputStream.Write(buffer, 0, length); context.Response.Flush(); buffer = new Byte[10000]; dataToRead = dataToRead - length; } else { dataToRead = -1; } } } catch (Exception ex) { NR.Error.Log.LogType(ex.ToString()); } finally { if (iStream != null) { iStream.Close(); } } } else { NR.Error.Log.LogType("找不到文件!"); } } public bool IsReusable { get { return false; } } }}
[解决办法]
using System;using System.Collections;using System.Data;using System.Linq;using System.Web;using System.Web.Services;using System.Web.Services.Protocols;using System.Xml.Linq;namespace Asiastar.NR.Ajax{ /// <summary> /// $codebehindclassname$ 的摘要说明 /// </summary> [WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] public class Handler1 : IHttpHandler { public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/plain"; string id = context.Request["id"].ToString();//获取资源的编号 System.IO.Stream iStream = null; byte[] buffer = new Byte[10000]; int length; long dataToRead; NRBLL.File bf = new Asiastar.NRBLL.File(); Guid guid = new Guid(id); if (bf.FN_SerchPathByFileId(guid).Tables[0].Rows[0]["FilePath"] != null)//判断数据库路径是否存在 { string filepath = bf.FN_SerchPathByFileId(guid).Tables[0].Rows[0]["FilePath"].ToString();//获取资源完整路径 D:\资源文件\600cc139-14cf-448e-9e50-daa972d35e01.jpg string Oidfilename = bf.FN_SerchPathByFileId(guid).Tables[0].Rows[0]["FileNam"].ToString();//旧文件名称 //string filename = System.IO.Path.GetFileName(filepath);//获取文件名称+后缀名 600cc139-14cf-448e-9e50-daa972d35e01.JPG //int index = filepath.IndexOf("."); //string filetype = filepath.Substring(index).ToLower();//后缀名 //string newfilename = Oidfilename; //string filepath1 = bf.FN_SerchPathByFileId(guid).Tables[0].Rows[0]["FilePath"].ToString().Substring(0,filepath.Length - 8); try { string fileName = HttpUtility.UrlEncode(System.Text.Encoding.UTF8.GetBytes(Oidfilename));//解码(注意这里2层解码) Oidfilename = Oidfilename.Replace("+", "%20"); //将“+”替换成“空格” iStream = new System.IO.FileStream(filepath, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.Read); dataToRead = iStream.Length; context.Response.ContentType = "application/octet-stream"; context.Response.AddHeader("Content-Disposition", "attachment; filename=" + HttpUtility.UrlEncode(Oidfilename, System.Text.Encoding.UTF8)); //下载的时候下载原来的文件名称 while (dataToRead > 0) { if (context.Response.IsClientConnected) { length = iStream.Read(buffer, 0, 10000); context.Response.OutputStream.Write(buffer, 0, length); context.Response.Flush(); buffer = new Byte[10000]; dataToRead = dataToRead - length; } else { dataToRead = -1; } } } catch (Exception ex) { NR.Error.Log.LogType(ex.ToString()); } finally { if (iStream != null) { iStream.Close(); } } } else { NR.Error.Log.LogType("找不到文件!"); } } public bool IsReusable { get { return false; } } }}
[解决办法]
为什么不直接用
Response.TransmitFile(string filename)
[解决办法]
TransmitFile(input, output, buffer);
怎么实现的?我记得 Response.TransmitFile 只有一个参数: FileName。
且是不缓存直接输出到客户端的。
如果文件不是太大,完全可以直接用 Response.TransmitFile 也不要自己用 FileStream 打开文件。
另外,注意你 FileStream 的最后一个参数: System.IO.FileShare.Inheritable
如果是可读的话应该是 System.IO.FileShare.Read
[解决办法]
System.IO.Stream input = new System.IO.FileStream(context.Server.MapPath(filePath), System.IO.FileMode.Open, System.IO.FileAccess.ReadWrite, System.IO.FileShare.Inheritable);
改成这样试试:
System.IO.Stream input = new System.IO.FileStream(context.Server.MapPath(filePath), System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.Read);
[解决办法]
TransmitFile(input, output, buffer);
怎么实现的?我记得 Response.TransmitFile 只有一个参数: FileName。
且是不缓存直接输出到客户端的。
如果文件不是太大,完全可以直接用 Response.TransmitFile 也不要自己用 FileStream 打开文件。
另外,注意你 FileStream 的最后一个参数: System.IO.FileShare.Inheritable
如果是可读的话应该是 System.IO.FileShare.Read ,且你只是下载,FileAccess用不着ReadWrite吧
[解决办法]