如何解决点网内存流-如何在不消耗所有内存的情况下等待一个
在开始我的问题时,我会说我认为我对如何解决该问题有根本的误解,并在这里寻求一些指导以潜在地了解我不知道的哈哈。
在没有深入研究具体细节的情况下,我遇到的问题是我正在基于流式传输来自S3的文件列表以编程方式编写Zip文件。当执行此操作作为对浏览器的响应时,它几乎不使用任何内存。但是,当我尝试将所有内容都写到一个内存流中并将Zip上传到S3时,它会占用大量内存,并且可以非常快地推翻Pod(服务在k8s中运行)。
在编写浏览器时,最终将返回它:
return new StreamingFileResult
(
contentType: download.GetContentType(),attachmentFileName: Path.GetFileName(download.Path),statusCode: HttpStatusCode.OK,writeResponseBody: async (s) => await download.WritetoStream(s,_downloadBufferSize,cancellationToken)
);
这是WritetoStream()
类中的ZipDownload
的样子:
public override async Task WritetoStream(Stream outputStream,int bufferSize,CancellationToken cancellationToken)
{
using (var zipArchive = new ZipArchive(outputStream,ZipArchiveMode.Create))
{
foreach (IDownload download in _downloads)
{
var zipEntry = zipArchive.CreateEntry(download.OutFilename);
using (var zipStream = zipEntry.open())
{
await download.WritetoStream(zipStream,bufferSize,cancellationToken);
// NOTE FOR STACK: This is from a separate method,specifically from an S3Download class
}
}
}
}
这部分不占用太多内存,这对我来说很有意义。通过将Task
写入lambda,它正在等待操作结束,并将所有内容都写回到outputStream
,该变量由所述lambda初始化。一切都很好。
现在对我来说最困难的部分是当我们将文件上传到S3而不是浏览器时。
它看起来像这样:
await upload.S3Upload(download,zipInfo.BucketName,zipInfo.FileName,cancellationToken);
// then in our uploader file
try
{
using(var fileTransferUtility = new TransferUtility(s3Client))
{
Logger.LogInfo("Starting Upload for {0}",keyName);
fileTransferUtility.Upload(await download.WritetoStream(_downloadBufferSize,cancellationToken),bucketName,keyName);
Logger.LogInfo("Finished Upload!");
return;
}
}
它使用的是WritetoStream
中ZipDownload
的重载版本,它返回一个Task<Stream>
public override async Task<Stream> WritetoStream(int bufferSize,CancellationToken cancellationToken)
{
Stream outputStream = new MemoryStream();
using (var zipArchive = new ZipArchive(outputStream,ZipArchiveMode.Create,true))
{
foreach (IDownload download in _downloads)
{
var zipEntry = zipArchive.CreateEntry(download.OutFilename);
using (var zipStream = zipEntry.open())
{
await download.WritetoStream(zipStream,cancellationToken);
}
}
}
return outputStream;
}
其背后的逻辑是因为TransferUtility
需要一个Stream
,而且我无法运行Lambda /委托,所以选择直接从Task返回Stream。
现在,我相信内存会变得疯狂的原因尤其是由于上传器文件中的fileTransferUtility.Upload(await download.WritetoStream(_downloadBufferSize,keyName);
以及我们如何拥有await download.WritetoStream()
。我认为它正在等待整个过程完成,然后再将结果泵入TransferUtility
,这与浏览器的实现有很大不同。我觉得我们不希望这不是积累而是 迭代 ,但是我不确定如何实现。
关于帮助我如何实现此目标的任何提示?也许有明显的我想念的地方=]
谢谢!
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。