ASP.NET上传大文件的构想

来源:互联网 发布:淘宝刷访客软件 编辑:程序博客网 时间:2024/05/18 00:08

前面研究了一下ASP.NET的进程模型,实际上就是为了“上传大文件”这个最终目的服务的。

大文件上传的可行性研究

互联网的应用从狭义上,或许可以看成“Request-and-Response”的过程。Request指的是客户端向服务器发出请求,Response是指服务器根据客户端的请求而做出的回应。而Response都一个回应时间的问题,所以在大文件上传过程中失败的可能性非常大,并且大多是超时的问题。
可行性的另一方面考虑是指文件上传过程的操作。通过<input type="file" />上传的文件,在ASP.NET 1.1时代,上传的文件会被完全载入内存,再进行写硬盘的操作。这就带来一个很大的问题,内存的空间毕竟有限,如果上传的文件比较大,又或者同时上传的人比较多,内存被耗尽,上传自然会失败。
实际上,最早在使用ASP经典上传空间ASPUpload时,就有这样的问题。用户通常反应上传超过100M的文件,到最后(指上传快结束时)会报错,并且之前所做的努力也白费了。因为资源从内存中被释放了。
需要知道的是,上传协议本身并没有规定服务器本身应该怎么来操作上传的文件。
ASP.NET 2.0时代,对文件上传的方式做了一些改进,启用硬盘临时文件的阈值(threshold)。该阀值是可配置。
<system.web>
  <httpRuntime maxRequestLength="4096" requestLengthDiskThreshold="256" />
</system.web>

以上默认值,规定了最大上传文件是4M,而当一个请求内容超过256K时就会启用硬盘作为缓存。所以在ASP.NET 2.0中服务器的内存不会因为客户端的异常请求而耗尽。

大文件上传的友好性研究

友好性也体现在两个方面。一是上传的进度显示和上传过程遇到意外状况的断点续传。
文件的上传都可以分块进行。所以对于上传进度的计算,一是在客户端进行,通过对本地文件大小和偏移量的计算,可以知道上传请求中的文件上传进度,这与实际文件上传进度有偏差,但把进度计算转嫁于客户端,实现了高效率;另一种是在服务端进行,通过保存在服务器硬盘上的临时文件来计算偏移量,从而得知实际文件上传的进度,数据准确,但效率很低。每次都必须在文件块保存之后,返回目前已保存文件块的容量值。
断点续传是一个在HTTP协议中,很少被采取的解决方案。最大的原因可能就是本地文件操作权限的问题。互联网的应用程序无法给<input type="file" />进行赋值,所以每次意外状况出现之后的再次上传,用户都不得不重新选择之前上传的同一个文件。此时,新问题出现。如果确认先后两次选择的文件是同一个文件?
要规避安全问题的话,或许ActiveX控件是个不错的选择,但ActiveX是IE Only的。我们必须得考虑不断增长的非IE用户。

大文件上传的思考(ASP.NET)

 1、想要上传大文件,首先得绕开maxRequestLength的限制。而大文件的定义,基本上就是不限制上传文件的大小;
2、想要绕开maxRequestLength的限制,就不能在客户端简单的通过Form把文件以multipart/form-data方式POST出来,然后服务器端接收、保存;
3、大文件上传和进度条显示的美好构想:在IIS将客户端发送的内容发送到Asp.NET的Pipeline时,随着服务器接收内容的同时,将文件内容写到服务器磁盘中,然后在Asp.NET的管道中只放入请求的对应的Form内容,同时提供服务器接收进度显示;
4、通过HttpModule,只需要在最早的事件BeginRequest中,处理数据接收,就可以避开Asp.NET的最大请求长度限制;
5、断点续传的美好构想:在重新上传文件时,先从服务器端读出临时文件的大小(字节数),然后再从该字节数开始读取本地文件。

0 0
原创粉丝点击