手机
当前位置:查字典教程网 >编程开发 >asp.net教程 >asp.net下实现支持文件分块多点异步上传的 Web Services
asp.net下实现支持文件分块多点异步上传的 Web Services
摘要:本文的客户端应用程序不包括ASP.NetWeb应用程序!本文假设URL:http://localhost/mywebservices/upd...

本文的客户端应用程序不包括ASP.NetWeb应用程序!

本文假设URL:http://localhost/mywebservices/updownload.asmx

共有4个程序文件(Web.Config就不赘述了)

ServerSide:

标题中所提到的"异步"其实在服务器端的程序并没有什么特殊的,而主要是通过客户端应用程序

异步调用相关WebMethod实现的!

1.updownload.asmx,位于IIS的某个Web共享目录,代码如下,只有一句话:

<%@WebServiceLanguage="c#"Codebehind="UpDownLoad.asmx.cs"Class="Service1"%>

2.updownload.asmx.cs,即:updownload.asmx的Codebehind,位于IIS的某个Web共享目录的bin子目录下,代码如下:

/*

本文件位于Web共享目录的bin子目录下,通过执行如下命令行编译:

csc/t:libraryupdownload.asmx.cs

*/

usingSystem.Diagnostics;

usingSystem.Web;

usingSystem.Web.Services;

usingSystem.IO;

usingSystem;

publicclassService1:System.Web.Services.WebService

{

[WebMethod]

publicstringHelloWorld()

{

return"HelloWorld";

}

//从WebMethod本身,其实看不出"同步"还是"异步"

[WebMethod(Description="为了支持多点分块异步上传文件,此方法必须由客户端预先调用,以便在服务器端生成指定FileName和Length大小的空白文件预定空间!建议客户端同步调用")]

publicstringCreateBlankFile(stringFileName,intLength)//建议由客户端同步调用

{

FileStreamfs=newFileStream(Server.MapPath(".")+""+FileName,FileMode.OpenOrCreate,FileAccess.ReadWrite,FileShare.None);

fs.Write(newbyte[Length],0,Length);

fs.Close();

fs=null;

returnFileName+"("+Length+")空白文件已经创建!";

}

[WebMethod(Description="提供一个用于一次完整上传整个文件的方法!建议客户端同步调用")]

publicstringUploadFileBytes(byte[]Bytes,stringFileName)

{

returnUploadFileChunkBytes(Bytes,0,FileName);

}

[WebMethod(Description="提供一个用于一次只上传由Position位置起始的,Bytes字节的FileName文件块存入服务器端相应文件的相应字节位置!建议客户端异步调用")]

//这里只要多提供一个Position参数,余下的再由客户端调用异步的该方法,就轻松达到目的了!

publicstringUploadFileChunkBytes(byte[]Bytes,intPosition,stringFileName)

{

try

{

FileStreamfs=newFileStream(Server.MapPath(".")+""+FileName,FileMode.OpenOrCreate,FileAccess.ReadWrite,FileShare.ReadWrite);

//该Bytes的字节要写到服务器端相应文件的从Position开始的字节

fs.Position=Position;

fs.Write(Bytes,0,Bytes.Length);

fs.Close();

fs=null;

returnFileName+"文件块:位置["+Position+","+(Position+Bytes.Length)+"]大小("+Bytes.Length+")上传成功!";

}

catch(Exceptione)

{

returne.Message;

}

}

[WebMethod]

publicbyte[]DownloadFileBytes(stringFileName)

{

if(File.Exists(FileName))

{

try

{

FileStreamfs=File.OpenRead(FileName);

inti=(int)fs.Length;

byte[]ba=newbyte[i];

fs.Read(ba,0,i);

fs.Close();

returnba;

}

catch

{

returnnewbyte[0];

}

}

else

{

returnnewbyte[0];

}

}

}

//=======================================================================

ClientSide:

3.UpDownloadProxy.cs:

本文件由如下命令生成

%VisualStudio.Net2003安装目录下的%SDKv1.1Binwsdl.exe

具体命令行如下:

wsdl.exe/l:CS/out:UpDownloadProxy.cshttp://localhost/MyWebServices/updownload.asmx?wsdl

生成的本地的客户端代理类代码里已经为每个WebMethod生成了可异步和同步执行的方法,例如:

publicstringHelloWorld(){}

publicSystem.IAsyncResultBeginHelloWorld(...){}

publicstringEndHelloWorld(...){}

下面是该命令行生成的完整的UpDownloadProxy.cs代码,就不修改了:

/*

通过执行如下命令行编译,生成UpDownloadProxy.dll:

csc/t:libraryUpDownloadProxy.cs

*/

//------------------------------------------------------------------------------

//<autogenerated>

//Thiscodewasgeneratedbyatool.

//RuntimeVersion:1.1.4322.573

//

//Changestothisfilemaycauseincorrectbehaviorandwillbelostif

//thecodeisregenerated.

//</autogenerated>

//------------------------------------------------------------------------------

//

//此源代码由wsdl,Version=1.1.4322.573自动生成。

//

usingSystem.Diagnostics;

usingSystem.Xml.Serialization;

usingSystem;

usingSystem.Web.Services.Protocols;

usingSystem.ComponentModel;

usingSystem.Web.Services;

///<remarks/>

[System.Diagnostics.DebuggerStepThroughAttribute()]

[System.ComponentModel.DesignerCategoryAttribute("code")]

[System.Web.Services.WebServiceBindingAttribute(Name="Service1Soap",Namespace="http://tempuri.org/")]

publicclassService1:System.Web.Services.Protocols.SoapHttpClientProtocol{

///<remarks/>

publicService1(){

this.Url="http://localhost/MyWebServices/updownload.asmx";

}

///<remarks/>

[System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://tempuri.org/HelloWorld",RequestNamespace="http://tempuri.org/",ResponseNamespace="http://tempuri.org/",Use=System.Web.Services.Description.SoapBindingUse.Literal,ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]

publicstringHelloWorld(){

object[]results=this.Invoke("HelloWorld",newobject[0]);

return((string)(results[0]));

}

///<remarks/>

publicSystem.IAsyncResultBeginHelloWorld(System.AsyncCallbackcallback,objectasyncState){

returnthis.BeginInvoke("HelloWorld",newobject[0],callback,asyncState);

}

///<remarks/>

publicstringEndHelloWorld(System.IAsyncResultasyncResult){

object[]results=this.EndInvoke(asyncResult);

return((string)(results[0]));

}

///<remarks/>

[System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://tempuri.org/CreateBlankFile",RequestNamespace="http://tempuri.org/",ResponseNamespace="http://tempuri.org/",Use=System.Web.Services.Description.SoapBindingUse.Literal,ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]

publicstringCreateBlankFile(stringFileName,intLength){

object[]results=this.Invoke("CreateBlankFile",newobject[]{

FileName,

Length});

return((string)(results[0]));

}

///<remarks/>

publicSystem.IAsyncResultBeginCreateBlankFile(stringFileName,intLength,System.AsyncCallbackcallback,objectasyncState){

returnthis.BeginInvoke("CreateBlankFile",newobject[]{

FileName,

Length},callback,asyncState);

}

///<remarks/>

publicstringEndCreateBlankFile(System.IAsyncResultasyncResult){

object[]results=this.EndInvoke(asyncResult);

return((string)(results[0]));

}

///<remarks/>

[System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://tempuri.org/UploadFileBytes",RequestNamespace="http://tempuri.org/",ResponseNamespace="http://tempuri.org/",Use=System.Web.Services.Description.SoapBindingUse.Literal,ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]

publicstringUploadFileBytes([System.Xml.Serialization.XmlElementAttribute(DataType="base64Binary")]System.Byte[]Bytes,stringFileName){

object[]results=this.Invoke("UploadFileBytes",newobject[]{

Bytes,

FileName});

return((string)(results[0]));

}

///<remarks/>

publicSystem.IAsyncResultBeginUploadFileBytes(System.Byte[]Bytes,stringFileName,System.AsyncCallbackcallback,objectasyncState){

returnthis.BeginInvoke("UploadFileBytes",newobject[]{

Bytes,

FileName},callback,asyncState);

}

///<remarks/>

publicstringEndUploadFileBytes(System.IAsyncResultasyncResult){

object[]results=this.EndInvoke(asyncResult);

return((string)(results[0]));

}

///<remarks/>

[System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://tempuri.org/UploadFileChunkBytes",RequestNamespace="http://tempuri.org/",ResponseNamespace="http://tempuri.org/",Use=System.Web.Services.Description.SoapBindingUse.Literal,ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]

publicstringUploadFileChunkBytes([System.Xml.Serialization.XmlElementAttribute(DataType="base64Binary")]System.Byte[]Bytes,intPosition,stringFileName){

object[]results=this.Invoke("UploadFileChunkBytes",newobject[]{

Bytes,

Position,

FileName});

return((string)(results[0]));

}

///<remarks/>

publicSystem.IAsyncResultBeginUploadFileChunkBytes(System.Byte[]Bytes,intPosition,stringFileName,System.AsyncCallbackcallback,objectasyncState){

returnthis.BeginInvoke("UploadFileChunkBytes",newobject[]{

Bytes,

Position,

FileName},callback,asyncState);

}

///<remarks/>

publicstringEndUploadFileChunkBytes(System.IAsyncResultasyncResult){

object[]results=this.EndInvoke(asyncResult);

return((string)(results[0]));

}

///<remarks/>

[System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://tempuri.org/DownloadFileBytes",RequestNamespace="http://tempuri.org/",ResponseNamespace="http://tempuri.org/",Use=System.Web.Services.Description.SoapBindingUse.Literal,ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]

[return:System.Xml.Serialization.XmlElementAttribute(DataType="base64Binary")]

publicSystem.Byte[]DownloadFileBytes(stringFileName){

object[]results=this.Invoke("DownloadFileBytes",newobject[]{

FileName});

return((System.Byte[])(results[0]));

}

///<remarks/>

publicSystem.IAsyncResultBeginDownloadFileBytes(stringFileName,System.AsyncCallbackcallback,objectasyncState){

returnthis.BeginInvoke("DownloadFileBytes",newobject[]{

FileName},callback,asyncState);

}

///<remarks/>

publicSystem.Byte[]EndDownloadFileBytes(System.IAsyncResultasyncResult){

object[]results=this.EndInvoke(asyncResult);

return((System.Byte[])(results[0]));

}

}

//=======================================================================

4.UpDownloadClient.cs:

该程序才是真正实现文件分块多点异步上传的核心代码:

/*

通过执行如下命令行编译:

cscupdownloadClient.cs/r:updownloadproxy.dll

*/

usingSystem;

usingSystem.IO;

publicclassClass1

{

staticvoidMain(string[]args)

{

//Download(ServerSidepath,ClientSidePath)

Download(@"e:test.jpg",@"f:test_local.jpg");

System.Console.WriteLine("downEnd");

System.Console.WriteLine("同步upfileexec...");

UploadFile(@"e:Northwind.mdb");

System.Console.WriteLine("同步upfileEndn");

System.Console.WriteLine("异步upchunksexec...");

UploadFileChunks(@"e:test.rar",64);

System.Console.ReadLine();

}

publicstaticvoidUploadFile(stringLocalFileName)

{

Service1xx=newService1();

FileStreamfs=newFileStream(LocalFileName,FileMode.Open);//ClientSidePath

byte[]buffer=newbyte[fs.Length];

fs.Read(buffer,0,buffer.Length);

//调用"同步执行"的本地WebSevices代理类的方法,相当于同步调用了WebMethod!

xx.UploadFileBytes(buffer,System.IO.Path.GetFileName(LocalFileName));

}

//指定要上传的本地文件的路径,及每次上传文件块的大小

publicstaticvoidUploadFileChunks(stringLocalFileName,intChunkSize)

{

Service1xx=newService1();

stringfilename=System.IO.Path.GetFileName(LocalFileName);

FileStreamfs=newFileStream(LocalFileName,FileMode.Open);//ClientSidePath

//fs=File.OpenRead(LocalFileName);

intr=(int)fs.Length;//用于记录剩余还未上传的字节数,初值是文件的大小

//调用"同步执行"的本地WebSevices代理类的方法,相当于同步调用了WebMethod!

//预定服务器端空间

xx.CreateBlankFile(filename,r);

intsize=ChunkSize*1024;

intk=0;//用于记录已经上传的字节数

i++;//用于记录上传的文件块数

while(r>=size)

{

byte[]buffer=newbyte[size];

fs.Read(buffer,0,buffer.Length);

//调用"异步执行"的本地WebSevices代理类的方法,相当于异步调用了WebMethod!

//该buffer的字节要写到服务器端相应文件的从Position=k开始的字节

xx.BeginUploadFileChunkBytes(buffer,k,filename,newAsyncCallback(UploadFileChunkCallback),xx);

k+=size;

r-=size;

i++;

}

if(r>0)//剩余的零头

{

byte[]buffer=newbyte[r];

fs.Read(buffer,0,buffer.Length);

//调用"异步执行"的本地WebSevices代理类的方法,相当于异步调用了WebMethod!

//该buffer的字节要写到服务器端相应文件的从Position=k开始的字节

xx.BeginUploadFileChunkBytes(buffer,k,filename,newAsyncCallback(UploadFileChunkCallback),xx);

i++;

}

fs.Close();

}

privatestaticinti=-1;//用于记录上传的文件块数

privatestaticvoidUploadFileChunkCallback(IAsyncResultar)

{

Service1x=(Service1)ar.AsyncState;

Console.WriteLine(x.EndUploadFileChunkBytes(ar));

if(--i==0)

{

Console.WriteLine("异步upallchunksend");

}

}

publicstaticvoidDownload(stringServerSideFileName,stringLocalFileName)

{

Service1xx=newService1();

byte[]ba=xx.DownloadFileBytes(ServerSideFileName);//ServerSidePath

FileStreamfs=newFileStream(LocalFileName,FileMode.Create);//ClientSidePath

fs.Write(ba,0,ba.Length);

fs.Close();

}

}

//===========================================================================

至此我们通过纯手工的方式完成了任务,之所以不用VS就是为了让码子简洁明了!

Microshaoft.Night就是这么平易近人!(PMPMPtoMS)

通过WebSevices上传文件非常简单,甚至比传统的httpWeb上传还简单!

同时较轻松地就实现了文件分块多点异步上传:

Server端代码没啥特殊的!

Client端代码稍微复杂些!

【asp.net下实现支持文件分块多点异步上传的 Web Services】相关文章:

asp.net实现文件无刷新上传方法汇总

运行asp.net时出现 http错误404-文件或目录未找到

asp.net repeater实现批量删除时注册多选框id到客户端

asp.net后台如何动态添加JS文件和css文件的引用?

asp.net自定义控件代码学习笔记

asp.net下创建、查询、修改带名称空间的 XML 文件的例子

asp.net操作xml增删改示例分享

asp.net 因为数据库正在使用的解决方法

asp.net AJAX实现无刷新获得数据

在asp.net下实现Option条目中填充前导空格的方法

精品推荐
分类导航