我有一个ASP.NET MVC应用程序,其中一个页面允许用户上传文件。这些文件将有几百兆字节。
我在客户端使用FineUploader,如果浏览器支持,它将使用FileAPI/XHR,否则将回退到Iframe/form并使用enctype="multipart whatever"。
因此,在服务器端,我需要评估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,直到整个文件上传完毕,它们才开始处理,如果文件非常大,则会占用很多Web服务器的RAM。
我找到了这篇文章:Streaming large file uploads to ASP.NET MVC,听起来很有前途,但我真的不知道代码在他的应用程序中位于哪个位置。
所以,问题是:如何在ASP.NET上传文件时将上传的文件流式传输到磁盘上?
更新
我刚看到一个关键细节,以前没有沉淀下来。来自HttpPostedFile文档:
默认情况下,所有请求(包括表单字段和上传的文件)大于256 KB都会缓冲到磁盘上,而不是保存在服务器内存中。
好的,这解决了担心在大型上传期间Web服务器的RAM利用率可能会飙升的问题。但是,仍然存在一个问题:在文件完全传输到Web服务器之后,服务器必须花费时间将其移动到最终目的地。如果文件系统操作是复制(如果目标位于另一物理磁盘上,则保证),则响应会不必要地延迟。
老实说,我可以通过增加上传处理程序/操作的响应超时来应对这个问题。但是,直接将字节流传输到它们的目标位置会更好。