这次在项目中,用到了大文件上传,要上传的文件有100多m,于是研究现在国内使用的大文件上传的
组件发现用的比较多的有两个控件aspnetupload 2.0和lion.web.uploadmodule,另外还有思归在它的博客
堂中所说的办法 http://blog.joycode.com/saucer/archive/2004/03/16/16225.aspx
两个控件的方法是:利用隐含的httpworkerrequest,用它的getpreloadedentitybody 和 readentitybody方法从iis为asp.net建立的pipe里分块读取数据。chris hynes为我们提供了这样的一个方案(用httpmodule),该方案除了允许你上传大文件外,还能实时显示上传进度。
lion.web.uploadmodule和aspnetupload 两个.net组件都是利用的这个方案。
当上传单文件时,两个软件的方法是一样的,继承httpmodule
httpapplication application1 = sender as httpapplication;
httpworkerrequest request1 = (httpworkerrequest) ((iserviceprovider) httpcontext.current).getservice(typeof(httpworkerrequest));
try
{
if (application1.context.request.contenttype.indexof("multipart/form-data") <= -1)
{
return;
}
//check the hasentitybody
if (!request1.hasentitybody())
{
return;
}
int num1 = 0;
timespan span1 = datetime.now.subtract(this.begintime);
string text1 = application1.context.request.contenttype.tolower();
byte[] buffer1 = encoding.ascii.getbytes(("/r/n--" + text1.substring(text1.indexof("boundary=") + 9)).tochararray());
int num2 = convert.toint32(request1.getknownrequestheader(11));
progress progress1 = new progress();
application1.context.items.add("filelist", new hashtable());
byte[] buffer2 = request1.getpreloadedentitybody();
num1 += buffer2.length;
string text2 = this.analysepreloadedentitybody(buffer2, "uploadguid");
if (text2 != string.empty)
{
application1.context.items.add("lionsky_uploadmodule_uploadguid", text2);
}
bool flag1 = true;
if ((num2 > this.uploadfilelength()) && ((0 > span1.totalhours) || (span1.totalhours > 3)))
{
flag1 = false;
}
if ((0 > span1.totalhours) || (span1.totalhours > 3))
{
flag1 = false;
}
string text3 = this.analysepreloadedentitybody(buffer2, "uploadfolder");
arraylist list1 = new arraylist();
requeststream stream1 = new requeststream(buffer2, buffer1, null, requeststream.filestatus.close, requeststream.readstatus.noread, text3, flag1, application1.context, string.empty);
list1.addrange(stream1.readbody);
if (text2 != string.empty)
{
progress1.filelength = num2;
progress1.receivedlength = num1;
progress1.filename = stream1.originalfilename;
progress1.filecount = ((hashtable) application1.context.items["filelist"]).count;
application1.application["_uploadguid_" + text2] = progress1;
}
if (!request1.isentireentitybodyispreloaded())
{
byte[] buffer4;
arraylist list2;
int num3 = 204800;
byte[] buffer3 = new byte[num3];
while ((num2 - num1) >= num3)
{
if (!application1.context.response.isclientconnected)
{
this.clearapplication(application1);
}
num3 = request1.readentitybody(buffer3, buffer3.length);
num1 += num3;
list2 = stream1.contentbody;
if (list2.count > 0)
{
buffer4 = new byte[list2.count + buffer3.length];
list2.copyto(buffer4, 0);
buffer3.copyto(buffer4, list2.count);
stream1 = new requeststream(buffer4, buffer1, stream1.filestream, stream1.fstatus, stream1.rstatus, text3, flag1, application1.context, stream1.originalfilename);
}
else
{
stream1 = new requeststream(buffer3, buffer1, stream1.filestream, stream1.fstatus, stream1.rstatus, text3, flag1, application1.context, stream1.originalfilename);
}
list1.addrange(stream1.readbody);
if (text2 != string.empty)
{
progress1.receivedlength = num1;
progress1.filename = stream1.originalfilename;
progress1.filecount = ((hashtable) application1.context.items["filelist"]).count;
application1.application["_uploadguid_" + text2] = progress1;
}
}
buffer3 = new byte[num2 - num1];
if (!application1.context.response.isclientconnected && (stream1.fstatus == requeststream.filestatus.open))
{
this.clearapplication(application1);
}
num3 = request1.readentitybody(buffer3, buffer3.length);
list2 = stream1.contentbody;
if (list2.count > 0)
{
buffer4 = new byte[list2.count + buffer3.length];
list2.copyto(buffer4, 0);
buffer3.copyto(buffer4, list2.count);
stream1 = new requeststream(buffer4, buffer1, stream1.filestream, stream1.fstatus, stream1.rstatus, text3, flag1, application1.context, stream1.originalfilename);
}
else
{
stream1 = new requeststream(buffer3, buffer1, stream1.filestream, stream1.fstatus, stream1.rstatus, text3, flag1, application1.context, stream1.originalfilename);
}
list1.addrange(stream1.readbody);
if (text2 != string.empty)
{
progress1.receivedlength = num1 + buffer3.length;
progress1.filename = stream1.originalfilename;
progress1.filecount = ((hashtable) application1.context.items["filelist"]).count;
if (flag1)
{
progress1.uploadstatus = progress.uploadstatusenum.uploaded;
}
else
{
application1.application.remove("_uploadguid_" + text2);
}
}
}
byte[] buffer5 = new byte[list1.count];
list1.copyto(buffer5);
this.populaterequestdata(request1, buffer5);
}
catch (exception exception1)
{
this.clearapplication(application1);
throw exception1;
}
而思归所说的方法使用mime也能上传大文件,在以下地址下载
http://krystalware.com/files/slickupload.zip
不过觉得的思归的方法容易很多
相关文章:
让asp.net默认的上传组件支持进度条反映
http://blog.joycode.com/dotey/archive/2005/06/12/53557.aspx // 宝玉
http://blog.joycode.com/saucer/archive/2004/03/16/16225.aspx // 思归
http://www.cnblogs.com/bestcomy/archive/2004/06/09/14267.aspx // bestcomy
http://krystalware.com/wiki/default.aspx/krystalwiki.uploadspike1
http://www.blueidea.com/tech/program/2005/2997.asp //ftp
通过web services上传和下载文件
http://dotnet.aspx.cc/showdetail.aspx?id=6381bd5f-51f3-4339-4239-1328564a1b2a
上传组件是如何不受settimeout限制的?
http://www.ietf.org/rfc/rfc1867.txt?number=1867
下载
http://support.microsoft.com/default.aspx?scid=kb;en-us;812406&product=aspnet
上传源代码下载:
openlabupload.rar
新闻热点
疑难解答
图片精选