能否提供一个C# Web API中处理大文件下载的完整接口实现示例?
时间: 2024-10-22 08:13:24 浏览: 32
当然可以。在C#中,为了更好地处理大文件下载,你可以创建一个基于分段上传的Web API。这里是一个基本的例子,使用了ASP.NET Core的MVC框架:
```csharp
using System;
using System.IO;
using System.Net;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
namespace YourNamespace.Controllers
{
[ApiController]
[Route("api/files")]
public class FilesController : ControllerBase
{
[HttpPost("download/{fileId}")]
public async Task<IActionResult> DownloadFile(long fileId, [FromForm] byte[] partialData, [FromHeader] RangeHeaderValue range)
{
try
{
// 验证文件ID和范围合法性
if (!ValidateDownloadRequest(fileId, range))
{
return BadRequest();
}
// 找到实际存储文件的路径
string filePath = GetFilePath(fileId);
if (!System.IO.File.Exists(filePath))
{
return NotFound($"File with ID {fileId} not found.");
}
// 开始下载,将接收到的部分数据追加到文件上
using (FileStream fileStream = new FileStream(filePath, FileMode.Append, FileAccess.Write))
{
fileStream.Write(partialData, 0, partialData.Length);
}
// 计算总长度
long fileSize = System.IO.FileInfo.FromFileName(filePath).Length;
// 创建HTTP响应
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.PartialContent);
response.Content.Headers.ContentLength = fileSize;
response.Content.Headers.Add("Content-Type", "application/octet-stream");
response.Content.Headers.ContentRange = new ContentRange(range.From, range.To ?? fileSize - 1, fileSize);
// 将整个文件作为响应发送
response.Content = new ByteArrayContent(File.ReadAllBytes(filePath));
return response;
}
catch (Exception ex)
{
return StatusCode((int)HttpStatusCode.InternalServerError, ex.Message);
}
}
private bool ValidateDownloadRequest(long fileId, RangeHeaderValue range)
{
// 这里只做了一个简化的验证,实际应用中应包含更多的错误检查和安全措施
return fileId > 0 && range != null && range.From >= 0 && range.To <= System.IO.FileInfo.FromFileName(GetFilePath(fileId)).Length;
}
private string GetFilePath(long fileId)
{
// 这里假设有一个映射文件ID到本地文件路径的函数,你需要根据实际情况替换
throw new NotImplementedException(); // 这里只是一个示例,需要你实际实现
}
}
}
```
这个例子中,`DownloadFile`方法接收一个文件ID、部分数据以及HTTP Range头。它首先验证请求的合法性,然后读取指定ID的文件,并将接收到的部分追加到已有的文件内容。当所有数据都接收完后,返回完整的文件内容。
请注意,这个示例假设你已经有一个机制将文件ID映射到实际的存储位置。在实际应用中,你需要实现`GetFilePath`方法来完成这部分工作。
阅读全文