源码如下:
/// <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://www.toymoban.com/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文章来源地址https://www.toymoban.com/news/detail-653269.html
到了这里,关于c#和pdf.js实现分片预览pdf的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!