System.OutOfMemoryException при чтении содержимого файла в веб-API - PullRequest
0 голосов
/ 13 февраля 2019

Я хочу отправить содержимое файла как memory stream в корзину S3 через Amazon Firehose.ниже моя попытка, которая отлично работает для небольших файлов, но у меня есть файл 1 ГБ, и я получаю {"Exception of type 'System.OutOfMemoryException' was thrown."}.

Мой фрагмент кода:

[HttpPost]
public async Task<bool> Upload()
{
    try
    {
        var filesReadToProvider = await Request.Content.ReadAsMultipartAsync();
        foreach (var stream in filesReadToProvider.Contents)
        {
            var fileBytes = await stream.ReadAsByteArrayAsync(); // THIS IS WHERE EXCEPTION COMES
            using (MemoryStream memoryStream = new MemoryStream(fileBytes))
            {
                PutRecordRequest putRecord = new PutRecordRequest();
                putRecord.DeliveryStreamName = myStreamName;
                Record record = new Record();
                record.Data = memoryStream;
                putRecord.Record = record;
                await kinesisClient.PutRecordAsync(putRecord);
            }
        }
    }
    catch (Exception e)
    {
        Console.WriteLine(e);
        throw;
    }    
    return true;
}

Я просмотрел эту ссылку OutOfMemoryExceptoin , но не смог ее понять.Пожалуйста, помогите мне.

Попытка 1:

var filesReadToProvider = await Request.Content.ReadAsMultipartAsync();
foreach (var stream in filesReadToProvider.Contents)
{
    var fileByte = await stream.ReadAsStreamAsync();
    MemoryStream _ms = new MemoryStream();
    fileByte.CopyTo(_ms); // EXCEPTION HERE
    try
    {
        PutRecordRequest putRecord = new PutRecordRequest();
        putRecord.DeliveryStreamName = myStreamName;
        Record record = new Record();
        record.Data = _ms;
        putRecord.Record = record;
        await kinesisClient.PutRecordAsync(putRecord);
    }
    catch (Exception ex)
    {
        Console.WriteLine("Failed to send record to Kinesis. Exception: {0}", ex.Message);
    }
}

Ответы [ 2 ]

0 голосов
/ 13 февраля 2019
[HttpPost]
public async Task<bool> Upload()
{
    try
    {
        using(var requestStream = await Request.Content.ReadAsStreamAsync())
        {
            PutRecordRequest putRecord = new PutRecordRequest();
            putRecord.DeliveryStreamName = myStreamName;
            Record record = new Record();
            record.Data = requestStream ;
            putRecord.Record = record;
            await kinesisClient.PutRecordAsync(putRecord);

        }
    }
    catch (Exception e)
    {
        Console.WriteLine(e);
        throw;
    }

    return true;
}

Это будет считывать данные кусками.Храните все в потоке, чтобы не хранить все байты в огромном массиве.

0 голосов
/ 13 февраля 2019

При чтении больших файлов я использую метод Readline () StreamReader.Он работает с большими файлами, поскольку управляет внутренним кэшированием файловой системы.Можете ли вы использовать этот метод вместо?Есть ли причина, по которой вы реализуете класс MemoryStream?У вас есть комментарий, спрашивающий, как ввести данные?Вы пытались использовать один из методов MemoryStream ???

https://docs.microsoft.com/en-us/dotnet/api/system.io.memorystream?view=netframework-4.7.2

Обновление:

Не уверен, что это полезно, так как кодсущественно отличается от того, что вы используете.Но ваш тоже не работает, так что просто предложение.

http://www.tugberkugurlu.com/archive/efficiently-streaming-large-http-responses-with-httpclient

...