Webapi传输大量大型文件[重复]

Posted

技术标签:

【中文标题】Webapi传输大量大型文件[重复]【英文标题】:Webapi transferring large quantities of large sized files [duplicate] 【发布时间】:2018-09-05 16:01:16 【问题描述】:

我目前正在计划通过 web api 的更新机制。传输的文件最大可达 1 GB,并且可以有 20 个客户端同时尝试获取文件。

每当我查看示例时,我都会发现类似这样的内容(简化):

public HttpResponseMessage GetFile(string name)

     var reqFile = @"C:\updates\" + name;
     var dataBytes = File.readAllBytes(reqFile)
     var dataStream new MemoryStream (dataBytes);
     HttpResponseMessage httprm = Request.CreateResponse(HttpStatusCode.OK);
     httprm.Content = new StreamContent(dataStream);
     httprm.Content.Headers.ContentDisposition = = new ContentDispositionHeaderValue("attachment");
     httprm.Content.Headers.ContentDisposition.FileName = name;
     httprm.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octetstream");

     return httprm;
     

现在,尽管在这些示例中,它们将整个文件加载到内存中(总共最多 20 GB,因此对于我的情况下客户端需要下载的单个文件.....这不是最佳的,即使我只加载每个特定文件只有在我遇到类似问题时才会出现,因为它们可能在不同的更新步骤中)。

我看到的一个选项是,我事先将文件分成 10 MB 的块,让客户端下载它,然后再将它放在一起。这样一来,文件的最大内存占用量将为 200 MB,这是一个更可接受的区域。

我仍然想知道是否有另一种方法来完成下载,而​​不必为 20 个并发客户端使用 20 GB 内存(除了拆分之外)?

【问题讨论】:

这只是个坏例子,不要使用它。直接使用FileStream,而不是毫无理由地将整个文件复制到MemoryStream @evk 我只找到了上面带有内存流的示例。所以我可以在那里“只”使用文件流作为流内容,它不会将文件放入我的内存或客户端,而只是在客户端加载数据并用它做任何他想做的事情时一次传输“块”(如果到那里的文件流然后直接到硬盘上)? 是的,只要通过FileStream 就可以了。它将读取带有小块的文件(取决于缓冲区大小,通常为 1MB)并直接写入 http 响应(因此基本上是网络套接字)。确保不锁定该流(因此打开读取并使用Read 共享),以便多个请求可以同时从中读取。 并且不要忘记确保从客户端正确下载此文件。例如,如果您使用类似 DownloadData 或任何类似的 api 将整个响应从服务器拉入内存 - 这次您将无缘无故地膨胀客户端内存。而是将响应流直接复制到客户端上的文件 (responseStream.CopyTo(localFileStream) @evk tnx btw 我敢说这也是我问题的答案 【参考方案1】:

尝试使用PushStreamContent。它将流推送回客户端,而无需将其加载到内存中。

Here'sStephen Cleary 的优秀文章使用 PushStreamContent,唯一的区别是它在发送之前压缩文件,所以你应该修改它,或者更好的是,发送压缩版本以节省带宽。

【讨论】:

不是 pushstreamcontent 主要用于视频流吗? (***.com/questions/16168683/…) 还是我忽略了什么? 是的,但它也适用于您描述的场景。即使对于大于 2 gbs 的文件,我也能完美地做到这一点 你可以使用PushStreamContent,但为什么呢?普通的StreamContent 可以用更少的代码完成同样的工作。

以上是关于Webapi传输大量大型文件[重复]的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET Core - 从 WebApi 提供静态内容 [重复]

C# webApi----H5_app后台制作--参数的传输(对于懒得安分webApi参数传输不行的补充)

C# WebApi 中的实时 FLV 流式传输

mvc webapi跨域帖子[重复]

无法在 Angularjs 重复指令中显示 WEBAPI 数据

postman用post大量传值请求webapi