public class DownloadCore<T> { private HttpRequestMessage request; private IFileProvider<T> fileProvider; private T requestModel; public DownloadCore(HttpRequestMessage request,IFileProvider<T> fileProvider,T requestModel) { this.request = request; this.fileProvider = fileProvider; this.requestModel = requestModel; } public HttpResponseMessage Download() { if (requestModel == null) { //抛出异常 } if (!fileProvider.Exists(requestModel)) { //抛出异常 } long fileLength = fileProvider.GetLength(requestModel); if (fileLength == 0) { //抛出异常 } ContentInfo contentInfo = GetContentInfoFromRequest(fileLength); Stream stream = PartialStream.GetPartialStream(fileProvider.Open(requestModel), contentInfo.From, contentInfo.To); if (stream == null) { //抛出异常 } HttpContent content = new StreamContent(stream, AppSettings.BufferSize); return SetResponse(content, contentInfo, fileLength, fileProvider.GetFileName(requestModel)); } private ContentInfo GetContentInfoFromRequest(long entityLength) { var result = new ContentInfo { From = 0, To = entityLength - 1, IsPartial = false, Length = entityLength }; RangeHeaderValue rangeHeader = request.Headers.Range; if (rangeHeader != null && rangeHeader.Ranges.Count != 0) { //仅撑持一个range if (rangeHeader.Ranges.Count > 1) { //抛出异常 } RangeItemHeaderValue range = rangeHeader.Ranges.First(); if (range.From.HasValue && range.From < 0 || range.To.HasValue && range.To > entityLength - 1) { //抛出异常 } result.From = range.From ?? 0; result.To = range.To ?? entityLength - 1; result.IsPartial = true; result.Length = entityLength; if (range.From.HasValue && range.To.HasValue) { result.Length = range.To.Value - range.From.Value + 1; } else if (range.From.HasValue) { result.Length = entityLength - range.From.Value; } else if (range.To.HasValue) { result.Length = range.To.Value + 1; } } return result; } private HttpResponseMessage SetResponse(HttpContent content, ContentInfo contentInfo, long entityLength, string fileNameWithExtend) { HttpResponseMessage response = new HttpResponseMessage() ; response.Headers.AcceptRanges.Add("bytes"); response.StatusCode = contentInfo.IsPartial ? HttpStatusCode.PartialContent : HttpStatusCode.OK; response.Content = content; response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment"); response.Content.Headers.ContentDisposition.FileName = fileNameWithExtend; response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); response.Content.Headers.ContentLength = contentInfo.Length; if (contentInfo.IsPartial) { response.Content.Headers.ContentRange = new ContentRangeHeaderValue(contentInfo.From, contentInfo.To, entityLength); } return response; } }
,