.net从服务端下载文件(可以断点续传)
public void DownFile(string guid) { var fileTransfer = new FileTransfer(); var directoryPath = Path.Combine(InitInfo.Config_GarbagePath, "FileImport", guid); fileTransfer.ChunkTransfer(System.Web.HttpContext.Current, GetDownFilePath(directoryPath)); HttpContext.Response.Flush(); //删除临时文件 // Utility.DeleteDirectory(directoryPath); }
public bool ChunkTransfer(HttpContext httpContext, string filePathName) { bool result = false; if (!System.IO.File.Exists(filePathName)) { httpContext.Response.StatusCode = 404; return false; } long startPostion = 0; long endPostion = 0; string fileName = Path.GetFileName(filePathName); using (FileStream fileStream = new FileStream(filePathName, FileMode.Open, FileAccess.Read, FileShare.Read)) { using (BinaryReader br = new BinaryReader(fileStream)) { long fileLength = fileStream.Length; string lastUpdateTime = System.IO.File.GetLastWriteTimeUtc(filePathName).ToString("r"); string eTag = HttpUtility.UrlEncode(fileName, Encoding.UTF8) + lastUpdateTime;//恢复下载时提取请求头; if (httpContext.Request.Headers["If-Range"] != null) { if (httpContext.Request.Headers["If-Range"].Replace("\"", "") != eTag) {//文件修改过 httpContext.Response.StatusCode = 412;//预处理失败 return false; } } httpContext.Response.Clear(); httpContext.Response.Buffer = false; httpContext.Response.AddHeader("Accept-Ranges", "bytes"); httpContext.Response.AppendHeader("ETag", "\"" + eTag + "\""); httpContext.Response.AppendHeader("Last-Modified", lastUpdateTime);//把最后修改日期写入响应 httpContext.Response.ContentType = "application/octet-stream"; if (httpContext.Request.UserAgent.IndexOf("MSIE") > -1 || (httpContext.Request.UserAgent.IndexOf("like Gecko") > -1)) { fileName = HttpUtility.UrlEncode(fileName, Encoding.UTF8).Replace("+", "%20"); } if (httpContext.Request.UserAgent.ToLower().IndexOf("firefox") > -1) { httpContext.Response.AddHeader("Content-Disposition", "attachment;filename=\"" + fileName + "\""); } else { httpContext.Response.AddHeader("Content-Disposition", "attachment;filename=" + fileName); } httpContext.Response.AddHeader("Connection", "Keep-Alive"); httpContext.Response.ContentEncoding = Encoding.UTF8; if (httpContext.Request.Headers["Range"] != null)//续传 { httpContext.Response.StatusCode = 206;//续传标识 string[] range = httpContext.Request.Headers["Range"].Split(new char[] { '=', '-' }); startPostion = long.Parse(range[1]);//已经下载的字节数 if (startPostion < 0 || startPostion >= fileLength) { return false; } if (string.IsNullOrEmpty(range[2]))//只指定请求文件起始 { httpContext.Response.AddHeader("Content-Range", string.Format(" bytes {0}-{1}/{2}", startPostion, fileLength - 1, fileLength)); httpContext.Response.AddHeader("Content-Length", (fileLength - startPostion).ToString()); } else//指定请求文件范围 { endPostion = long.Parse(range[2]); httpContext.Response.AddHeader("Content-Range", string.Format(" bytes {0}-{1}/{2}", startPostion, endPostion - startPostion - 1, fileLength)); httpContext.Response.AddHeader("Content-Length", (endPostion - startPostion).ToString()); } } else {//非续传 httpContext.Response.AddHeader("Content-Range", string.Format(" bytes {0}-{1}/{2}", startPostion, fileLength - 1, fileLength)); httpContext.Response.AddHeader("Content-Length", (fileLength - startPostion).ToString()); } br.BaseStream.Seek(startPostion, SeekOrigin.Begin); long maxCount = (long)Math.Ceiling((fileLength - startPostion + 0.0) / TransferBuffer);//分块下载,剩余部分可分成的块数 for (long i = 0; i < maxCount && httpContext.Response.IsClientConnected; i++) { httpContext.Response.BinaryWrite(br.ReadBytes(TransferBuffer)); httpContext.Response.Flush(); if (TransferSleep > 0) { Thread.Sleep(TransferSleep); } } result = true; } } return result; }