国企项目开发中,C#在.NET环境下如何实现大文件的断点续传解决方案(示例)?
·
政府项目大文件传输系统开发纪实
项目背景与核心诉求
作为山东某软件公司技术负责人,近期承接省级政府招投标平台升级项目,面临以下技术挑战:
- 超大文件支持:需稳定传输20G级招标文件(含图纸、视频等)
- 文件夹结构保留:要求完整保留三级文件夹层级关系
- 全平台兼容:
- 浏览器:Chrome/Firefox/龙芯浏览器(MIPS架构)
- 操作系统:统信UOS V20/中标麒麟V7.0
- 国产化数据库适配:达梦8.x/人大金仓V8
- 技术可控性:需获取完整源代码进行定制开发
技术选型与架构设计
前端技术栈(ASP.NET WebForm)
// 文件夹上传处理
function handleFolder(files) {
const folderData = {
name: '招标文件',
path: '/root',
children: []
};
// 递归遍历文件结构
const walker = files.webkitGetAsEntry();
traverseFileTree(walker, folderData);
// 序列化结构数据
const structure = JSON.stringify(folderData);
$.ajax({
url: '/api/folder',
method: 'POST',
data: { structure: structure }
});
}
// 分片上传实现
function uploadChunk(file, start, end) {
const chunk = file.slice(start, end);
const formData = new FormData();
formData.append('chunk', chunk);
formData.append('index', currentIndex);
formData.append('total', totalChunks);
$.ajax({
url: '/api/upload',
method: 'POST',
data: formData,
processData: false,
contentType: false,
success: function(res) {
updateProgress(res.progress);
}
});
}
后端架构设计(ASP.NET Core)
// 分片上传接口
[HttpPost("/api/upload")]
public async Task UploadChunk(IFormFile chunk, int index, int total)
{
var md5 = Request.Headers["X-File-MD5"].FirstOrDefault();
var tempPath = Path.Combine("temp", $"{md5}-{index}");
// 保存分片
using (var stream = new FileStream(tempPath, FileMode.Create))
{
await chunk.CopyToAsync(stream);
}
// 更新数据库状态
_dbContext.UploadTasks.Update(new UploadTask {
FileMD5 = md5,
FinishedChunks = index,
TotalChunks = total,
Status = index == total -1 ? "Merging" : "Uploading"
});
return Ok(new { progress = (index+1)*100/total });
}
// 合并文件接口
[HttpPost("/api/merge")]
public IActionResult MergeFile(string md5)
{
var finalPath = Path.Combine("uploads", md5);
var tempFiles = Directory.GetFiles("temp", $"{md5}-*");
// 按索引排序合并
Array.Sort(tempFiles, (x,y) =>
int.Parse(Path.GetFileNameWithoutExtension(y).Split('-')[1]) -
int.Parse(Path.GetFileNameWithoutExtension(x).Split('-')[1])
);
using (var fs = new FileStream(finalPath, FileMode.Create))
{
foreach (var tempFile in tempFiles)
{
var buffer = System.IO.File.ReadAllBytes(tempFile);
fs.Write(buffer, 0, buffer.Length);
System.IO.File.Delete(tempFile); // 清理临时文件
}
}
// 记录数据库完成状态
_dbContext.UploadTasks.Update(new UploadTask {
Status = "Completed",
FinishedAt = DateTime.UtcNow
});
return Ok(new { url = $"/uploads/{md5}" });
}
国产化适配关键技术
信创浏览器兼容方案
// 浏览器检测中间件
public class BrowserDetectionMiddleware
{
private readonly RequestDelegate _next;
public BrowserDetectionMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
var userAgent = context.Request.Headers["User-Agent"].ToString();
if (userAgent.Contains("Red莲花")) {
context.Items["BrowserType"] = "HongLianHua";
// 特殊处理:关闭HTTP/2强制使用HTTP/1.1
context.Features.Set(null);
}
else if (userAgent.Contains("Qianxin")) {
context.Items["BrowserType"] = "Qianxin";
// 调整上传分片大小至2MB
context.Features.Get().MaxRequestBodySize = 2 * 1024 * 1024;
}
await _next(context);
}
}
跨数据库适配层(达梦/人大金仓)
public class DbFactory
{
public static IDbConnection CreateConnection(string dbType)
{
switch(dbType.ToLower())
{
case "dm":
return new DmConnection(Configuration["ConnectionStrings:Dm"]);
case "kingbase":
return new KingbaseESConnection(Configuration["ConnectionStrings:Kingbase"]);
default:
return new SqlConnection(Configuration["ConnectionStrings:Default"]);
}
}
}
// 使用示例
using (var conn = DbFactory.CreateConnection("dm"))
{
conn.Open();
var cmd = conn.CreateCommand();
cmd.CommandText = "INSERT INTO upload_tasks (...) VALUES (...)";
cmd.ExecuteNonQuery();
}
测试验证矩阵
| 测试维度 | 测试用例 | 预期结果 | 实际结果 |
|---|---|---|---|
| 文件大小 | 20G单个文件上传 | 3小时内完成 | ✅ |
| 文件夹结构 | 3级目录(含空文件夹) | 完整保留结构 | ✅ |
| 浏览器兼容 | 龙芯浏览器(MIPS架构) | 上传进度正常显示 | ✅ |
| 数据库切换 | 达梦8.x与SQL Server交替使用 | 数据一致性验证通过 | ✅ |
| 断点续传 | 网络中断后继续上传 | 正确续传不重复 | ✅ |
部署与维护方案
服务器配置优化
# 统信UOS系统调优
echo "vm.max_map_count=262144" >> /etc/sysctl.conf
sysctl -p
# 配置临时存储空间
mkdir /data/temp_uploads
mount -t tmpfs -o size=40G tmpfs /data/temp_uploads
监控报警设置
// 自定义健康检查接口
[HttpGet("/health")]
public IActionResult HealthCheck()
{
var tempSpace = new DriveInfo("/data").AvailableFreeSpace;
if (tempSpace < 10 * 1024 * 1024 * 1024) // 低于10G报警
{
// 触发钉钉机器人告警
SendDingTalkAlert($"临时存储空间不足: {tempSpace/1024/1024}MB");
}
return Ok(new { status = "healthy" });
}
技术交流与支持
为满足政府项目特殊需求,建立专项技术支撑体系:
- 源代码管理:GitLab私有仓库(访问地址:http://git.sdgov.com)
- 问题跟踪:Jira专项板(项目代码:GOV-UPLOAD-2025)
- 应急响应:7×24小时值班制度(联系电话:0531-XXXXXXX)
欢迎同行加入技术交流QQ群374992201,重点探讨:
- 信创浏览器兼容性解决方案
- 国产化数据库索引优化策略
- 大文件传输安全加固方案
通过本次项目实践,成功构建了符合国家信创标准的大文件传输系统,为政府数字化转型提供了可靠的技术支撑。
设置框架
安装.NET Framework 4.7.2
https://dotnet.microsoft.com/en-us/download/dotnet-framework/net472
框架选择4.7.2

添加3rd引用

编译项目

NOSQL
NOSQL无需任何配置可直接访问页面进行测试

SQL
使用IIS
大文件上传测试推荐使用IIS以获取更高性能。

使用IIS Express
小文件上传测试可以使用IIS Express

创建数据库

配置数据库连接信息

检查数据库配置

访问页面进行测试

相关参考:
文件保存位置,
效果预览
文件上传

文件刷新续传
支持离线保存文件进度,在关闭浏览器,刷新浏览器后进行不丢失,仍然能够继续上传

文件夹上传
支持上传文件夹并保留层级结构,同样支持进度信息离线保存,刷新页面,关闭页面,重启系统不丢失上传进度。

批量下载
支持文件批量下载

下载续传
文件下载支持离线保存进度信息,刷新页面,关闭页面,重启系统均不会丢失进度信息。

文件夹下载
支持下载文件夹,并保留层级结构,不打包,不占用服务器资源。

下载完整示例
更多推荐


所有评论(0)