欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 房产 > 家装 > 实战:大数据上传与下载的技术难题剖析与解决

实战:大数据上传与下载的技术难题剖析与解决

2026/5/10 22:03:23 来源:https://blog.csdn.net/m0_65664914/article/details/144567563  浏览:    关键词:实战:大数据上传与下载的技术难题剖析与解决

一、背景

        基于一些业务场景,比如客户端需要将本地的数据文件上传服务端保存,或者进行大文件传输,现代社会中,大文件上传是一个常见的需求,因为大数据时代,数据的体量越来越大, 在这些大数据上传的场景下,或多或少都会遇到相同的技术难题,尤其是在下面的一些场景中:

1、视频、音频文件内容上传
  • 短视频平台
  • 音乐播放平台
  • 在线教育课程平台
2、大数据上传
  • 机器训练模型大数据
  • 企业系统日志数据、数据库数据
  • 数据仓、数据湖
3、医疗影像数据上传
  • 患者的医疗检查等影像数据
  • 就诊问诊、病例与治疗记录
4、软件与游戏分发
  • 大型游戏安装包下载
  • 游戏补丁与更新包
5、云备份与恢复
  • 用户将大量重要数据备份到云端
  • 云端数据恢复     

二、遇到的难题:

  • 文件大小限制:大数据文件通常非常大,可能达到数GB甚至更大。需要处理大文件上传的技术方案。
  • 数据完整性:备份和恢复过程中需要确保数据的完整性和一致性,避免数据丢失或损坏。
  • 传输效率:大规模数据备份和恢复需要高效的传输方案,减少时间消耗。
  • 安全性:备份数据通常包含敏感信息,需要确保数据传输和存储的安全性。
  • 可扩展性:系统需要具备良好的可扩展性,能够处理不断增长的数据量。
  • 存储和处理:上传后的文件需要高效存储和处理,确保文件完整性和安全性。

三、上传、下载代码实现

        比如服务端接口接收文件上传的格式如下:

{file:文件对象Author:文件作者FileDesc:文件描述CreatTime:文件创建时间
}
1、上传文件的代码Demo
using System;
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;class Program
{static async Task Main(string[] args){var filePath = "D:\\Test\\test.zip";var url = "http://localhost:5000/api/upload/uploadFile";using (var client = new HttpClient()){// 设置超时时间为10分钟client.Timeout = TimeSpan.FromMinutes(10);using (var content = new MultipartFormDataContent()){byte[] fileBytes = File.ReadAllBytes(filePath);var fileContent = new ByteArrayContent(fileBytes);fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data");content.Add(fileContent, "file", Path.GetFileName(filePath));content.Add(new StringContent("张三"), "Author");content.Add(new StringContent("测试数据压缩包"), "FileDesc");content.Add(new StringContent("2024-12-15 14:23:56"), "CreatTime");try{var response = await client.PostAsync(url, content);if (response.IsSuccessStatusCode){Console.WriteLine("File uploaded successfully.");}else{Console.WriteLine($"Error: {response.StatusCode}");}}catch (Exception ex){Console.WriteLine($"An error occurred: {ex.Message}");}}}}
}
2、API接口:接收多部分表单数据(multipart/form-data)接口代码Demo
[Route("api/[controller]")]
[ApiController]
public class UploadController : ControllerBase
{[HttpPost("uploadFile")]public IActionResult Upload([FromForm] IFormFile file, [FromForm] string? Author, [FromForm] string? FileDesc, [FromForm] string? CreatTime){if(file == null || file.Length == 0){return BadRequest("No file upload!");}// 保存文件到本地目录var filePath = Path.Combine("UploadedFiles", file.FileName);Directory.CreateDirectory(Path.GetDirectoryName(filePath));using (var stream = new FileStream(filePath, FileMode.Create)){file.CopyTo(stream);}// 将字段信息生成实体类var Data = new{author = Author,fileDesc = FileDesc,creatTime = CreatTime,fileName = file.FileName,path = filePath};//保存到数据库...return Ok(new { message = "File uploaded successfully.", filePath });}
2、ASP .NET CORE 应用程序对请求体大小的限制

 需要支持允许传输大数据文件,需要增加如下设置:

客户端:设置多部分表单的Body长度限制,Program.cs文件

// 配置FormOptions类: 在 ASP.NET Core 中用于配置处理表单数据的选项,特别是多部分表单(multipart/form-data)上
builder.Services.Configure<FormOptions>(options =>
{options.MultipartBodyLengthLimit = 10L * 1024 * 1024 * 1024; //10G
});

服务端:配置Kestrel服务器限制,Program.cs文件

// 配置Kestrel服务器限制
builder.WebHost.ConfigureKestrel(options =>
{options.Limits.MaxRequestBodySize = 10L * 1024 * 1024 * 1024; //10Goptions.Limits.KeepAliveTimeout = TimeSpan.FromMinutes(30);options.Limits.RequestHeadersTimeout = TimeSpan.FromMinutes(30);
});

可以看到,同时我们还需要设置请求的超时时间很长,防止请求时间过期导致大数据传输中断。 

四、难题突破

        虽然上面的代码案例实现了文件的上传与下载保存,但是对于一些大文件的传输,面临的主要难题包括文件大小限制、网络不稳定、上传速度慢、数据隐私和安全、数据一致性、高并发、版本控制、带宽消耗等,需要逐一解决,才能保证大数据文件的上传过程稳定、高效、安全。

1、分块上传、断点续传、流式处理、异步处理
// GET api/<UploadController>/5
[HttpGet("OffsetUpload")]
public async void Get()
{var filePath = "D:\\TX_L10TestLog\\text.txt";          var url = "https://localhost:8085/api/Upload";var fileInfo = new FileInfo(filePath);var fileName = Path.GetFileNameWithoutExtension(filePath);long totalSize = fileInfo.Length;int chunkSize = 10 * 1024 * 1024; //分块上传,每块10MBusing(HttpClient client = new HttpClient()){//断点续传:检查服务端已经接收到的文件部分,从上次中断的位置继续上传var response = await client.GetAsync($"{url}/getOffSize?fileName={fileName}");response.EnsureSuccessStatusCode();string result = await response.Content.ReadAsStringAsync();long offset = long.Parse(result);//分块传输for(; offset < totalSize; offset += chunkSize){using(var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read)){fileStream.Seek(offset, SeekOrigin.Begin);byte[] buffer = new byte[chunkSize];int bytesRead = await fileStream.ReadAsync(buffer, 0, chunkSize);using(var content = new ByteArrayContent(buffer,0, bytesRead)) {//请求头中添加Content-Range信息,以便服务端知道当前块的位置和总大小content.Headers.Add("Content-Range", $"bytes {offset}-{offset + bytesRead - 1}/{totalSize}");content.Headers.Add("File-Name", fileInfo.Name);var responeUpolad = await client.PostAsync(url+"/UploadByOffsize", content);responeUpolad.EnsureSuccessStatusCode();}}}}
}
[HttpGet("getOffSize")]
public IActionResult GetOffsize([FromQuery] string fileName)
{string UploadFolder = "uploads";var filePath = Path.Combine(UploadFolder, $"{fileName}.tmp");if (System.IO.File.Exists(filePath)){var fileinfo = new FileInfo(filePath);return Ok(fileinfo.Length.ToString());}return Ok("0");
}
// POST api/<UploadController>
[HttpPost("UploadByOffsize")]
public async Task<IActionResult> UploadByOffsize()
{var request = HttpContext.Request;//检查并解析Content-Range和File-Name头信息if (!request.Headers.ContainsKey("Content-Range") || !request.Headers.ContainsKey("File-Name")){return BadRequest("Missing headers");}var contentRange = request.Headers["Content-Range"].ToString();var range = contentRange.Split(new char[] { ' ', '-', '/' }, StringSplitOptions.RemoveEmptyEntries);long start = long.Parse(range[1]);long end = long.Parse(range[2]);long total = long.Parse(range[3]);string UploadFolder = "uploads";var fileName = request.Headers["File-Name"].ToString();var filePath = Path.Combine(UploadFolder, $"{fileName}.tmp");Directory.CreateDirectory(Path.GetDirectoryName(filePath));using (var fileStream = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None)){//使用FileStream以追加模式写入文件,将接收到的块数据写入指定位置fileStream.Seek(start, SeekOrigin.Begin);await request.Body.CopyToAsync(fileStream);}//如果接收到的块是最后一块,则完成文件上传并重命名文件if (end + 1 == total){// File upload completedSystem.IO.File.Move(filePath, Path.Combine(UploadFolder, fileName));}return Ok();
}
2、考虑压缩,采用更精确的压缩算法
压缩原理:
  • TAR:只是简单地将多个文件和目录合并成一个文件,不进行任何压缩。
  • GZIP:使用DEFLATE算法进行压缩,这是一种基于LZ77和哈夫曼编码的无损数据压缩算法。
  • ZIP:也使用DEFLATE算法,但每个文件单独压缩,并且包含文件目录信息以支持随机访问。
压缩效率: 
  • TGZ通常会有更好的压缩率,特别是在处理大量小文件时
tgz压缩代码实现:
public class TgzHelperClass
{public void myCreateTgz(string sourceFilePath, string tgzFilePath){// 先创建一个.tar的打包文件string tarFilePath = Path.ChangeExtension(tgzFilePath, ".tar");// 首先将文件打包成.tarusing (var tarStream = File.OpenWrite(tarFilePath)){using (var tarArchive = TarArchive.Create()){tarArchive.AddEntry(Path.GetFileName(sourceFilePath), sourceFilePath);tarArchive.SaveTo(tarStream, new WriterOptions(CompressionType.None));}}// 然后使用GZIP算法将.tar打包文件压缩成.tgz文件using (var tarStream = new FileStream(tarFilePath, FileMode.Open, FileAccess.Read))using (var tgzStream = new FileStream(tgzFilePath, FileMode.Create, FileAccess.Write))using (var gzipStream = new GZipStream(tgzStream, CompressionLevel.Optimal)){tarStream.CopyTo(gzipStream);}// 最后删除临时中间.tar文件File.Delete(tarFilePath);}
}

五、总结

        在这些业务场景中,大文件上传面临的主要难题包括文件大小限制、网络不稳定、上传速度慢、数据隐私和安全、数据一致性、高并发处理、版本控制、带宽消耗、数据预处理、成本控制等。为了应对这些挑战,技术方案需要综合考虑分块上传、断点续传、流式处理、异步处理、数据加密、压缩传输、负载均衡等技术手段,确保大文件上传过程稳定、高效、安全。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词