【发布时间】:2019-02-13 15:55:18
【问题描述】:
我想通过 Amazon Firehose 将文件内容作为 memory stream 发送到 S3 存储桶。下面是我的尝试,它适用于小文件,但我有一个 1 GB 的文件,我得到了{"Exception of type 'System.OutOfMemoryException' was thrown."}。
我的代码sn-p:
[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);
}
}
【问题讨论】:
-
为什么要将整个流读入一个数组?如果要流式传输字节,请使用
ReadAsStreamAsync。 -
尝试使用
GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce; GC.Collect();或者如果文件很大,将其分成块。 -
您应用于文件内容的逻辑在这种情况下是相关的。您应该尽量避免读取所有文件然后处理它,而是分块读取和处理。
标签: c# .net asp.net-web-api asp.net-web-api2 out-of-memory