【发布时间】:2020-12-22 01:27:34
【问题描述】:
我正在做一个项目,我在后端填充一些 pdf,然后我将这些 pdf 转换为 byte[] 列表,该列表被合并到一个非常大的数组中,最后通过响应体发回作为记忆流。 我的问题是这是大量数据,在获取要合并的字节数组列表的过程中,我使用了大量内存。 我想知道是否不是将最终合并的 byte[] 转换为 Memory Stream 并将其添加到响应正文中;我可以创建几个 Memory Stream 对象,在创建它们时将它们附加到 Response.Body 中吗?或者,我想知道是否有一种方法可以使用一个内存流并继续添加它作为为每个 pdf 文档创建每个新字节 []?
编辑:这可能有点啰嗦,但我对我原来的帖子太含糊了。在我想做的事情的核心,我有几个 pdf 文档,它们每个都有几页长。它们中的每一个都在下面的代码中表示为 filesToMerge 列表中的 byte[] 项之一。理想情况下,我想一个一个地浏览这些并将它们转换为内存流,并在一个循环中一个接一个地发送给客户端。但是,当我尝试执行此操作时,我收到响应正文已发送的错误。有没有办法在响应正文中附加一些内容,以便每次通过循环更新?
[HttpGet("template/{formId}/fillforms")]
public void FillForms(string formId/*, [FromBody] IList<IDictionary<string, string>> fieldDictionaries*/)
{
List<byte[]> filesToMerge = new List<byte[]>();
// For testing
var mockData = new MockData();
IList<IDictionary<string, string>> fieldDictionaries = mockData.GetMock1095Dictionaries();
foreach(IDictionary<string, string> dictionary in fieldDictionaries)
{
var populatedForm = this.dataRepo.PopulateForm(formId, dictionary);
// write to rb
filesToMerge.Add(populatedForm);
}
byte[] mergedFilesAsByteArray = this.dataRepo.GetMergedByteArray(filesToMerge);
this.SendResponse(formId + "_filled.pdf", new MemoryStream(mergedFilesAsByteArray));
}
private void SendResponse(string formName, MemoryStream ms, IDictionary<string, string> fieldData = null)
{
Response.Clear();
Response.ContentType = "application/pdf";
Response.Headers.Add("content-disposition", $"attachment;filename={formName}.pdf");
ms.WriteTo(Response.Body);
}
【问题讨论】:
-
这个问题有点开放式,虽然这个故事是对你在做什么的高级视图,很难知道你实际在做什么,以及我们如何在不看到实际情况的情况下减少你的分配代码
-
您可以将您的方法 FillForm 更改为 IActionResult(公共 IActionResult FillForms)的返回类型,然后您将能够使用现有方法来公开文件或内容。请参阅此链接以获取示例 c-sharpcorner.com/article/fileresult-in-asp-net-core-mvc2
标签: c# .net-core memory-management