我有一个ASP.NET MVC应用程序,该应用程序的页面允许用户上传文件。文件将是几百兆字节。
我在客户端使用FineUploader,如果浏览器支持,它将使用FileAPI / XHR,否则将使用enctype =“ multipart what”退回到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。
我发现了这一点:Streaming large file uploads to 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; } }
}

在Web.config中注册:

<system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
    <handlers>
        <add name="UploadHandler" verb="POST"
            path="/upload"
            type="UploadHandler"
        resourceType="Unspecified"/>
    </handlers>
</system.webServer>

创建带有表单的页面:



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

关于asp.net - 在ASP.NET中流式传输大文件上载,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13976517/

10-14 11:52
查看更多