源碼如下:
/// <summary>/// 文件處理/// </summary>[RoutePrefix("api/fs")]public class FileStoreController : ApiController{/// <summary>/// 文件預覽/// </summary>/// <param name="filepath">文件路徑</param>/// <returns></returns>[Description("文件預覽")][HttpGet, Route("preview")]public HttpResponseMessage Preview([Description("文件路徑")] string filepath){try{FileInfo fileInfo = new FileInfo(filepath);long fileSize = fileInfo.Length;var response = Request.CreateResponse();StreamContent content = null;// 下載的字節范圍long startByte = 0, endByte = fileSize - 1, totalByte = fileSize;if (Request.Headers.TryGetValues("range", out IEnumerable<string> rangeHeader)){// 斷點續傳var rangeString = rangeHeader.FirstOrDefault();var match = Regex.Match(rangeString, @"bytes=(\d+)-(\d+)");// 文件總大小totalByte = fileSize;startByte = long.Parse(match.Groups[1].Value);endByte = long.Parse(match.Groups[2].Value);// 返回http狀態response.StatusCode = HttpStatusCode.PartialContent;long bytesToRead = endByte - startByte + 1;var contentStream = ReadFileInRange(filepath, startByte, endByte);content = new StreamContent(contentStream);content.Headers.ContentLength = Convert.ToInt32(endByte - startByte + 1);}else{// 文件總大小totalByte = fileSize;// 下載起始位置startByte = 0;// 下載結束位置endByte = totalByte - 1;response.StatusCode = HttpStatusCode.OK;using (var ms = new MemoryStream()){content = new StreamContent(ms);}}//表明服務器支持分片加載response.Headers.AcceptRanges.Add("bytes");//Content - Range: bytes 0 - 65535 / 408244,表明此次返回的文件范圍content.Headers.ContentRange = new ContentRangeHeaderValue(startByte, endByte, totalByte);告知瀏覽器這是一個字節流,瀏覽器處理字節流的默認方式就是下載content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");response.Content = content;//需要設置此屬性,否則瀏覽器默認不會讀取到響應頭中的Accept-Ranges屬性,因此會認為服務器端不支持分片,所以會直接全文下載response.Headers.Add("Access-Control-Expose-Headers", "*");response.Headers.Add("Access-Control-Allow-Headers", "range,Accept-Ranges,Content-Range,Content-Type,X-CAF-Authorization-Token,sessionToken,X-TOKEN,Cache-Control,If-Modified-Since");return response;}catch (Exception ex){return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, "服務器內部異常");}}private static MemoryStream ReadFileInRange(string filePath, long startByte, long endByte){// 驗證參數if (startByte < 0 || endByte < startByte){throw new ArgumentException("Invalid byte range");}try{using (FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read)){// 計算要讀取的字節數long bytesToRead = endByte - startByte + 1;// 創建緩沖區byte[] buffer = new byte[bytesToRead];// 將文件流的位置設置為開始字節fileStream.Seek(startByte, SeekOrigin.Begin);// 讀取字節到緩沖區fileStream.Read(buffer, 0, (int)bytesToRead);// 創建一個MemoryStream來存儲讀取的字節MemoryStream resultStream = new MemoryStream(buffer);return resultStream;}}catch (Exception ex){// 在這里處理任何異常,比如文件未找到或讀取錯誤Console.WriteLine("Error: " + ex.Message);return null;}}
源代碼github地址:
https://github.com/LeoMingGit/dotNetPractiseCollect/blob/master/%E5%88%86%E7%89%87%E9%A2%84%E8%A7%88pdf/FileStoreController.cs