在ASP.NET中流式传输大型文件上传如何实现?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (124)

我有一个ASP.NET MVC应用程序,其页面允许用户上传文件。这些文件将有几百兆字节。

我在客户端使用FineUploader,如果浏览器支持它,将使用FileAPI / XHR,否则将使用enctype =“multipart whatever”回退到Iframe / form。

所以在服务器端我需要评估Request.Files.Count > 1。如果true,这是一个旧类上传,我保存文件,Request.Files[0].InputStream.CopyTo(myFileStream)否则我会这样做Request.InputStreawm.CopyTo(myFileStream)

以下是我编写的一些实际代码,它可以完成以下工作:https : //github.com/ronnieoverby/file-uploader/blob/master/server/ASP.NET%20MVC%20C%23/FineUpload.cs

这一切都很好,但在我的测试中,我注意到,在整个文件上传之前,ASP.NET MVC控制器操作和HttpHandler都不会开始处理,如果文件非常大,这样会很糟糕,因为这意味着它占用了很多网络服务器的RAM。

我发现:将大文件上传到ASP.NET MVC听起来很有前途,但我真的不知道代码驻留在他的应用程序中的位置。

所以,问题是:如何在ASP.NET上传过程中上传文件到磁盘?

我刚刚看到一个没有沉入的关键细节。从HttpPostedFile文档:

默认情况下,大于256 KB的所有请求(包括表单字段和上载文件)都会缓存到磁盘,而不是保存在服务器内存中。

好的,这解决了在大型上传期间Web服务器的RAM利用率可能激增的问题。但是,仍然存在一个问题:在文件完全传输到Web服务器之后,服务器必须花时间将其移动到最终目的地。如果文件系统操作是复制(如果目标位于另一个物理磁盘上,则可以保证),则响应延迟不必要。

老实说,我可以通过增加上传处理程序/操作的响应超时来解决这个问题。但是,将字节直接传输到目标将会很好。

提问于
用户回答回答于

如果上传和流媒体正在使用有价值的服务器资源,那么可能想看看将媒体文件托管在某种云上。ASP.NET可以使用Rackspace,Amazon Cloud API让用户直接将文件上传到CDN网络,然后以这种方式提供内容。许多人仍然不选择使用云令我惊讶!一旦你去CDN你永远不会回去。此外,对于大多数CDN,还会为上传容器提供流式URL,以支持许多不同类型的电影,并且其照明速度非常快,不仅可供用户上传,还可以永远在网站上以慢速播放结果。

用户回答回答于

可以以完全自定义的方式处理上传,而无需使用HttpRequest.GetBufferlessInputStream方法进行缓冲 。基本上,可以访问原始传入数据并随意随意执行任何您想要的操作。

我刚刚创建了一个小样本,它将原始请求内容保存到文件中:

  1. 创建处理器: public class UploadHandler : IHttpHandler { public void ProcessRequest(HttpContext context) { using (var stream = context.Request.GetBufferlessInputStream()) using (var fileStream = File.Create("c:\\tempfile.txt")) { stream.CopyTo(fileStream); } } public bool IsReusable { get { return true; } } }
  2. 在Web.config中注册: <system.webServer> <modules runAllManagedModulesForAllRequests="true"/> <handlers> <add name="UploadHandler" verb="POST" path="/upload" type="UploadHandler" resourceType="Unspecified"/> </handlers> </system.webServer>
  3. 使用表单创建一个页面:

<form action="/upload" method="post" enctype='multipart/form-data'> <input type="file" name="aa" id="aa"/> <input type="submit"/> </form>

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励