.NET 8 WebAPI文件下载包含断点续传和取消下载

一、文件下载(取消下载服务端不会知道)

cs 复制代码
	/// <summary>
    /// 文件下载
    /// </summary>
    /// <param name="FilePath">文件相对路径</param>
    /// <returns></returns>
    [HttpGet]
    public IActionResult DownloadFile([FromQuery] string FilePath)
    {
        try
        {
            string filePath = GlobalConfig.Com.WebPath.UserResourcePath + FilePath;  //文件物理路径
            if (!System.IO.File.Exists(filePath))
            {
                LogHelper.Info($"客户端下载文件失败:文件不存在,文件绝对路径:{filePath}", LogHelper.GetCurSourceFileName(), LogHelper.GetLineNum());
                return new EmptyResult();
            }

            string fileName = Path.GetFileName(filePath);
            var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite, 4096, true);  //异步读取文件

            return File(fileStream, "application/octet-stream", fileName, true);  //为true时,支持断点续传
        }
        catch (Exception ex)
        {
            LogHelper.Error("客户端下载文件出现异常:", ex, LogHelper.GetCurSourceFileName(), LogHelper.GetLineNum());
            return new EmptyResult();
        }
    }

二、.NET Core 写Response.Body下载(取消下载服务端知道)

cs 复制代码
	/// <summary>
    /// 文件中转下载
    /// </summary>
    /// <param name="FilePath">文件相对路径</param>
    /// <returns></returns>
    [HttpGet]
    public void DownloadFile1([FromQuery] string FilePath)
    {
        try
        {
            string filePath = GlobalConfig.Com.WebPath.UserResourcePath + FilePath;  //文件物理路径
            if (!System.IO.File.Exists(filePath))
            {
                LogHelper.Info($"客户端下载文件失败:文件不存在,文件绝对路径:{filePath}", LogHelper.GetCurSourceFileName(), LogHelper.GetLineNum());
                return;
            }
            string fileName = Path.GetFileName(filePath);
            long beginPosition = 0;
            var fs = new FileStream(filePath, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite, 4096, true);

            //断点续传
            string rangeStr = Request.Headers["range"];  //range 参数格式:byte=1024-,这个是http协议的格式,也可以自定义格式
            if (!string.IsNullOrEmpty(rangeStr))  //断点续传
            {
                string byteStr = rangeStr.Split("=")?[1];
                if (!string.IsNullOrEmpty(byteStr))
                {
                    var byteArr = byteStr.Split("-");
                    if (byteArr != null && byteArr.Length > 1)
                    {
                        beginPosition = Convert.ToInt64(byteArr[0]);
                    }
                }
            }

            HttpContext.Response.ContentType = "application/octet-stream";
            HttpContext.Response.Headers.Append("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode(fileName));
            HttpContext.Response.Headers.Append("Charset", "utf-8");
            HttpContext.Response.Headers.Append("Access-Control-Expose-Headers", "Content-Disposition");
            int bufferSize = 1024;  //每次读取1MB到服务器内存

            using (HttpContext.Response.Body)
            {
                long contentLength = fs.Length;
                HttpContext.Response.ContentLength = contentLength;
                byte[] buffer;
                long hasRead = 0;
                while (hasRead < contentLength)
                {
                    if (HttpContext.RequestAborted.IsCancellationRequested)
                    {
                        //取消下载会进来,这里可以做一些操作。。。。。
                        break;
                    }

                    fs.Seek(hasRead, SeekOrigin.Begin);
                    buffer = new byte[bufferSize];
                    //从下载文件中读取bufferSize(1024字节)大小的内容到服务器内存中
                    int currentRead = fs.Read(buffer, 0, bufferSize);
                    HttpContext.Response.Body.WriteAsync(buffer, 0, currentRead);
                    HttpContext.Response.Body.Flush();
                    hasRead += currentRead;
                }

                if (hasRead == contentLength)  //下载完成
                {
                    //下载完成之后要做的事。。。。
                    return;
                }
            }

        }
        catch (Exception ex)
        {
            LogHelper.Error("客户端下载文件出现异常:", ex, LogHelper.GetCurSourceFileName(), LogHelper.GetLineNum());
            return;
        }
    }
相关推荐
geovindu5 分钟前
java: Backtracking Algorithm
java·开发语言·windows·后端·算法·回溯算法
NWU_LK9 分钟前
【WebFlux】第六篇 —— 全链路响应式与数据库交互
java·数据库
一只小菜鸡..10 分钟前
南京大学 操作系统 (JYY) 学习笔记:Hello, OS World! (程序的机器视角)
java·笔记·学习
叶总没有会16 分钟前
3.2 构建AI智能体项目扩展知识
java·数据库·人工智能·spring·ai
Lakers-2417 分钟前
1987年6月10日晚上23-24点出生性格、运势和命运
java
唐青枫20 分钟前
Java Jetty 实战详解:从嵌入式 HTTP 服务到 Spring Boot 容器替换
java
不好听61321 分钟前
React 父子组件通信:从 Todo 应用理解单向数据流
前端·react.js
_lucas29 分钟前
做了一个glsl在线调试工具
前端·javascript·three.js
腻害兔9 小时前
【若依项目-产品经理视角】深度拆解 RuoYi-Vue-Pro 商城模块:从商品管理到交易引擎,50 张表撑起一整套电商系统
java·大数据·vue.js·产品经理·ai编程
不好听6139 小时前
从一行 JSX 到屏幕像素:前端开发者必须懂的浏览器渲染管线
前端