簡體   English   中英

在Web API中讀取文件內容時出現System.OutOfMemoryException

[英]System.OutOfMemoryException when reading content of a file in a Web API

我想通過Amazon Firehose將文件內容作為memory stream發送到S3存儲桶。 下面是我的嘗試,該嘗試對小文件有效,但是我有一個1 GB的文件,並且正在獲取{"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);
    }
}
[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;
}

這將分塊讀取數據。 將所有內容保留在Stream中,這樣就不會將所有字節保留在一個巨大的數組中。

讀取大文件時,我使用StreamReader的Readline()方法。 它在大型文件上工作,因為它在內部管理文件系統緩存。 您可以使用這種方法嗎? 您為什么要實現MemoryStream類? 您有一條評論,詢問如何注入數據? 您是否嘗試使用MemoryStream的方法之一???

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

更新:

不確定這是否有幫助,因為代碼與您使用的代碼有很大不同。 但是,您的也不起作用,所以只是一個建議。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM