Чтение частичного содержимого с помощью ASP.NET CoreC#

Место общения программистов C#
Ответить
Anonymous
 Чтение частичного содержимого с помощью ASP.NET Core

Сообщение Anonymous »

Моя цель — эффективно читать данные входной формы с помощью моего контроллера API ASP.NET. Идея заключается в том, что пользователь API предоставляет заголовок Content-Range и данные формы, а API считывает только фрагмент данных, указанный в этом заголовке.
Поскольку тело запроса это поток без поиска - его можно прочитать только один раз, я не могу просто использовать метод Stream.Seek.
Вот что я пробовал:

Код: Выделить всё

private const ushort DefaultBufferSize = 4096;

Код: Выделить всё

private protected async Task ReadRangedContentAsync(Func readCallback)
{
if (!Request.HasFormContentType ||
!MediaTypeHeaderValue.TryParse(Request.ContentType, out var contentType) ||
!contentType.Boundary.HasValue ||
!Request.Headers.TryGetValue(HeaderNames.ContentRange, out var contentRangeValues) ||
!ContentRangeHeaderValue.TryParse(contentRangeValues.First(), out var contentRange) ||
!contentRange.HasRange)
{
return new Result(HttpStatusCode.UnsupportedMediaType);
}

var offset = contentRange.From.Value;
var length = contentRange.To.Value - offset + 1;

var reader = new MultipartReader(contentType.Boundary.Value, Request.Body);

var section = await reader.ReadNextSectionAsync();

if (section is null)
return new Result(HttpStatusCode.BadRequest);

var buffer = new byte[length];

await SkipBytesAsync(section.Body, offset);

await ReadBytesAsync(section.Body, buffer);

return await readCallback(buffer);
}

Код: Выделить всё

private static async Task SkipBytesAsync(Stream stream, long bytesToSkip)
{
var trashBin = new byte[DefaultBufferSize];

while (bytesToSkip != 0)
{
// TODO: Add number overflow check.
var count = (int)Math.Min(trashBin.LongLength, bytesToSkip);

bytesToSkip -= await stream.ReadAsync(trashBin, 0, count);
}
}

Код: Выделить всё

private static async Task ReadBytesAsync(Stream stream, byte[] buffer)
{
int bytesRead;
var totalBytesRead = 0;

while (totalBytesRead < buffer.Length)
{
var length = Math.Min(DefaultBufferSize, buffer.Length - totalBytesRead);
var memory = buffer.AsMemory(totalBytesRead, length);

bytesRead = await stream.ReadAsync(memory);

if (bytesRead is 0)
break;

totalBytesRead += bytesRead;
}
}
Мой вопрос: есть ли лучший способ прочитать поток без поиска? Например, я использую массив размером 4 КБ, который перезаписывается снова и снова, чтобы «осушить» поток, пока я не достигну позиции, описанной в заголовке, и мне любопытно, есть ли лучшее решение с точки зрения распределения памяти и т. д.

Подробнее здесь: https://stackoverflow.com/questions/791 ... p-net-core
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»