c# - 在 C# .Net 5 中分块文件
问题描述
我有大型视频文件,我试图将其分解成块并在服务器端重新组合。我一直在遵循本文中的建议,但我遇到了一些问题。
在捆绑块并通过网络发送它们的代码中,我有以下代码:
using (var client = new HttpClient(clientHandler))
{
var requestUri = ApiHelper.GetUrl("api/uploadFile");
client.BaseAddress = new Uri(requestUri);
client.DefaultRequestHeaders.Clear();
client.DefaultRequestHeaders.Add(Constants.ApiKeyHeaderName, Constants.RoadLivesApiAppKey);
using (var content = new MultipartFormDataContent())
{
var fileBytes = System.IO.File.ReadAllBytes(fileName);
var fileContent = new ByteArrayContent(fileBytes);
fileContent.Headers.ContentDisposition = new
ContentDispositionHeaderValue("attachment")
{
FileName = Path.GetFileName(fileName)
};
content.Add(fileContent);
try
{
var result = client.PostAsync(requestUri, content).Result;
rslt = true;
}
catch (Exception ex)
{
rslt = false;
}
}
}
在服务器端,我试图将该内容作为字节数组取出,以便在上传所有内容时重新组合文件。链接的文章建议 using Request.Files
,它在 .NET 5 中不存在。我尝试过using ,Request.Form.Files
但整体Request.Form
看起来是空的。
关于如何ByteArrayContent
从 Request 对象中获取信息有什么建议吗?符合我的Request.ContentLength
预期,但我不确定我可以从哪里获得这些数据。
我试图ByteArrayContent
从Request.Body
下面的选项中获取,但它没有按预期工作。
byte[] bodByteArray;
MemoryStream ms = new MemoryStream();
Request.BodyReader.CopyToAsync(ms);
//Request.Body.CopyToAsync(ms);
bodByteArray = ms.ToArray();
解决方案
一切都简单得多。这是一个示例:
服务器:
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
namespace Example.Controllers
{
[ApiController]
[Route("api/v1/[controller]")]
public class UploadController : ControllerBase
{
[HttpPost]
[ProducesResponseType(StatusCodes.Status200OK)]
public async Task PostAsync(
CancellationToken cancellationToken = default)
{
byte[] bytes;
// To get bytes, use this code (await is required, you missed it)
// But I recommend working with Stream in order not to load the server's RAM.
using (var memoryStream = new MemoryStream())
{
await Request.BodyReader.CopyToAsync(memoryStream, cancellationToken).ConfigureAwait(false);
bytes = memoryStream.ToArray();
}
// use bytes here
}
}
}
客户:
using System;
using System.IO;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
namespace Example.Apis
{
public partial class ExampleApi
{
public async Task UploadAsync(
string path,
CancellationToken cancellationToken = default)
{
using var client = new HttpClient();
using var request = new HttpRequestMessage(
HttpMethod.Post,
new Uri("https://localhost:5001/api/v1/upload"))
{
Content = new StreamContent(File.OpenRead(path)),
};
using var response = await client.SendAsync(
request, cancellationToken).ConfigureAwait(false);
response.EnsureSuccessStatusCode();
}
}
}
PS 除了示例,我建议您了解 Streams 作为处理大文件的正确方法。
推荐阅读
- c - 如何使用命令或调试文件在 open-vswitch 的内存池中查找空闲元素的大小?
- append - 我正在尝试向现有的 excel 文件添加更多内容,谁能告诉我 gembox.speadsheet 有什么方法可以使用吗?
- javascript - 在滚动容器内使用 React-dates 的 DateRangePicker
- parameter-passing - 将信息传递到在 Vaadin 8 中使用 BrowserWindowOpener 打开的新 Web 浏览器窗口/选项卡
- android - 显示多个从 Firebase 发送的活动通知
- reactjs - Redux-form 通过 POST 请求传递数据。
- django - 启动项目后 Django 运行服务器错误
- vba - VBA 中 worksheetfunction.match 属性的困难
- microsoft-graph-api - 使用 Microsoft.Graph 日历视图敏感度字段仅返回正常
- java - 跨多个 Java 应用程序的管道测量执行时间