源碼如下:
/// <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;
// 下載的字節(jié)范圍
long startByte = 0, endByte = fileSize - 1, totalByte = fileSize;
if (Request.Headers.TryGetValues("range", out IEnumerable<string> rangeHeader))
{
// 斷點續(xù)傳
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狀態(tài)
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);
告知瀏覽器這是一個字節(jié)流,瀏覽器處理字節(jié)流的默認方式就是下載
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))
{
// 計算要讀取的字節(jié)數
long bytesToRead = endByte - startByte + 1;
// 創(chuàng)建緩沖區(qū)
byte[] buffer = new byte[bytesToRead];
// 將文件流的位置設置為開始字節(jié)
fileStream.Seek(startByte, SeekOrigin.Begin);
// 讀取字節(jié)到緩沖區(qū)
fileStream.Read(buffer, 0, (int)bytesToRead);
// 創(chuàng)建一個MemoryStream來存儲讀取的字節(jié)
MemoryStream resultStream = new MemoryStream(buffer);
return resultStream;
}
}
catch (Exception ex)
{
// 在這里處理任何異常,比如文件未找到或讀取錯誤
Console.WriteLine("Error: " + ex.Message);
return null;
}
}
源代碼github地址:文章來源:http://www.zghlxwxcb.cn/news/detail-653269.html
https://github.com/LeoMingGit/dotNetPractiseCollect/blob/master/%E5%88%86%E7%89%87%E9%A2%84%E8%A7%88pdf/FileStoreController.cs文章來源地址http://www.zghlxwxcb.cn/news/detail-653269.html
到了這里,關于c#和pdf.js實現分片預覽pdf的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!