返回

ASP.NET Core文件上传优化方案:大文件上传、分片上传与断点续传完整实现指南

2026-07-26 ASP.NET Core 文件上传 125 0

在企业系统、网盘应用、视频平台以及后台管理系统中,文件上传一直是比较常见的功能。当用户上传几百 MB 甚至几个 GB 的文件时,传统的 ASP.NET Core 文件上传方式容易遇到超时、内存占用过高、网络中断导致重新上传等问题。

一个优秀的大文件上传方案通常需要支持文件分片上传、断点续传、上传进度显示以及失败自动恢复等功能。本文将介绍如何基于 ASP.NET Core 实现一套可靠的大文件上传方案。

ASP.NET Core 官方支持普通文件上传和流式上传两种方式。对于较小文件,可以使用 IFormFile 简化处理;而对于大文件场景,更推荐使用 Streaming 方式减少服务器内存压力。

为什么普通文件上传不适合大文件场景

很多开发者刚开始实现上传功能时,会直接使用 IFormFile:

[HttpPost("upload")]
public async Task<IActionResult> Upload(IFormFile file)
{
    var filePath = Path.Combine("uploads", file.FileName);

    using var stream = new FileStream(filePath, FileMode.Create);

    await file.CopyToAsync(stream);

    return Ok();
}

这种方式对于图片、文档等小文件没有问题,但是面对大文件时会存在几个明显问题。

  • 首先,服务器需要处理完整文件请求。如果多个用户同时上传大文件,会增加服务器内存和磁盘临时空间压力。
  • 其次,网络不稳定时,如果上传到 90% 失败,用户只能重新上传整个文件,体验非常差。
  • 另外,大文件上传过程中无法方便实现暂停、继续上传以及上传进度控制。

ASP.NET Core 文档也指出,大文件上传场景应该避免大量缓冲文件,而应该采用流式处理方式降低资源消耗。

大文件上传优化方案设计

一个完整的大文件上传系统通常包含以下几个步骤:

1. 文件切片

客户端首先将大文件拆分成多个小文件块。例如一个 1GB 文件:

文件大小:1024MB
分片大小:10MB

最终生成:
chunk_001
chunk_002
chunk_003
...
chunk_102

每个分片独立上传。

这样做的好处:

  • 单次请求数据量较小
  • 网络失败只需要重新上传失败分片
  • 可以实现多个分片并行上传
  • 支持暂停和恢复

目前很多网盘、云存储服务都采用类似方案。

2. 上传文件初始化

上传之前,客户端需要告诉服务器文件信息。

例如:

{
    "fileName": "video.mp4",
    "fileSize": 1073741824,
    "chunkSize": 10485760,
    "chunkCount": 103
}

服务器根据这些信息创建上传任务。

可以生成一个唯一 UploadId:a81f2c7e-9d55-4e7b,后续所有分片上传都通过这个 ID 关联。

数据库可以保存:

字段 说明
UploadId 上传任务ID
FileName 文件名称
FileSize 文件大小
ChunkCount 分片数量
UploadedChunks 已上传分片

ASP.NET Core实现分片上传接口

创建上传接口:

[HttpPost("chunk")]
public async Task<IActionResult> UploadChunk(
    IFormFile chunk,
    string uploadId,
    int chunkIndex)
{
    var folder = Path.Combine(
        "uploads",
        uploadId
    );

    if (!Directory.Exists(folder))
    {
        Directory.CreateDirectory(folder);
    }


    var filePath = Path.Combine(
        folder,
        $"{chunkIndex}.chunk"
    );


    using var stream =
        new FileStream(filePath, FileMode.Create);


    await chunk.CopyToAsync(stream);


    return Ok(new
    {
        success = true,
        chunkIndex
    });
}

上传后的目录结构:

uploads
 └── a81f2c7e
      ├──0.chunk
      ├──1.chunk
      ├──2.chunk
      └──3.chunk

每个分片独立保存。

实现断点续传功能

断点续传的核心是服务器知道哪些分片已经上传完成。

例如:

文件总分片:
0 1 2 3 4 5 6

服务器已有:
0 1 2 4

需要继续上传:
3 5 6

客户端上传前请求:GET /upload/status?id=xxxx

服务器返回:

{
    "uploadedChunks":[0,1,2,4]
}

前端收到后跳过已有分片。

这样即使浏览器关闭,再次打开上传页面,也可以继续上传。

文件合并处理

所有分片上传完成后,需要合并文件。ASP.NET Core 可以使用 FileStream 顺序读取:

public async Task MergeFile(
    string uploadId,
    string fileName,
    int chunkCount)
{
    var target =
        Path.Combine(
            "uploads",
            fileName);


    using var output =
        new FileStream(
            target,
            FileMode.Create);


    for(int i = 0; i < chunkCount; i++)
    {
        var chunkPath =
            Path.Combine(
                "uploads",
                uploadId,
                $"{i}.chunk");


        using var input =
            new FileStream(
                chunkPath,
                FileMode.Open);


        await input.CopyToAsync(output);
    }
}

合并完成:

0.chunk
1.chunk
2.chunk
3.chunk
↓
video.mp4

之后可以删除临时分片文件释放空间。

增加文件秒传功能

如果希望进一步优化上传体验,可以增加秒传功能。

实现方式:上传前计算文件 Hash。开始上传后,服务器查询数据库是否存在相同Hash。如果存在,直接返回上传成功,无需再次传输文件。

这种方式特别适合企业网盘、资源管理系统。

优化上传性能技巧

使用并发上传

不用等待分片逐个完成,可以同时上传多个分片,提高网络利用率。

使用流式写入

对于超大文件,不建议一次读取全部内容。

推荐:

await stream.CopyToAsync(fileStream);

避免:

byte[] buffer = File.ReadAllBytes();

否则可能导致服务器内存快速增长。

使用对象存储

生产环境中,不建议所有文件都存储在 Web 服务器本地。

可以考虑:

  • Azure Blob Storage
  • Amazon S3
  • 阿里云 OSS
  • 腾讯云 COS

这些服务本身针对大文件上传进行了优化。

大文件上传安全注意事项

文件上传接口必须做好安全处理。

常见措施包括:

1. 限制文件大小

services.Configure<FormOptions>(options =>
{
    options.MultipartBodyLengthLimit =
        1024 * 1024 * 1024;
});

2. 限制文件类型

例如:

允许:

.mp4
.jpg
.pdf


禁止:

.exe
.dll

3. 不要直接使用用户上传的文件名

建议:
  • 上传目录禁止执行权限
  • 对文件进行病毒扫描
  • 检查文件真实 MIME 类型

ASP.NET Core 官方也建议对上传文件进行验证,并避免直接信任用户提供的文件名。

总结

ASP.NET Core 实现大文件上传时,简单使用 IFormFile 只能满足基础需求。如果面对视频、压缩包、安装包等大文件场景,更推荐采用分片上传 + 断点续传方案。

完整的大文件上传流程通常包括:文件切片、上传任务管理、分片保存、断点检测、文件合并以及安全验证。通过这种设计,可以有效解决大文件上传失败、服务器压力过高以及用户体验差等问题,同时也为后续扩展秒传、多线程上传、对象存储提供基础。

对于需要处理大量文件的 ASP.NET Core 项目,例如企业网盘、CMS系统、在线教育平台,这套方案具有较高的实用价值。

顶部