Ron*_*rby 18 asp.net asp.net-mvc file-upload
我有一个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都不会开始处理,如果文件非常大,那就不好了,因为这意味着它占用了很多Web服务器的RAM.
我发现这一点:将大型文件上传到ASP.NET MVC,听起来很有希望,但我真的不知道代码在他的应用程序中的位置.
所以,问题是:如何在上传仍在ASP.NET中时将上传的文件流式传输到磁盘?
我刚看到一个之前没有陷入的关键细节.从HttpPostedFile文档:
默认情况下,大于256 KB的所有请求(包括表单字段和上载文件)都缓冲到磁盘,而不是保存在服务器内存中.
好的,这解决了在大型上传期间Web服务器的RAM利用率可能会飙升的担忧.但是,仍然存在一个问题:在文件完全传输到Web服务器之后,服务器必须花时间将其移动到它的最终目的地.如果文件系统操作是副本(如果目标位于另一个物理磁盘上,则保证),则响应会不必要地延迟.
老实说,我可以通过增加上传处理程序/操作的响应超时来解决这个问题.但是,将字节直接流式传输到目的地会很不错.
您可以使用完全自定义的方式处理上传,而无需使用缓冲
HttpRequest.GetBufferlessInputStream
方法.基本上,您可以访问原始传入数据,并可随意使用它执行任何操作.
我刚刚创建了一个小样本,它将原始请求内容保存到文件中:
创建处理程序
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; } }
}
Run Code Online (Sandbox Code Playgroud)在Web.config中注册:
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<handlers>
<add name="UploadHandler" verb="POST"
path="/upload"
type="UploadHandler"
resourceType="Unspecified"/>
</handlers>
</system.webServer>
Run Code Online (Sandbox Code Playgroud)创建一个包含表单的页面:
Run Code Online (Sandbox Code Playgroud)<form action="/upload" method="post" enctype='multipart/form-data'> <input type="file" name="aa" id="aa"/> <input type="submit"/> </form>
归档时间: |
|
查看次数: |
9231 次 |
最近记录: |