无为清净楼资源网 Design By www.qnjia.com
本文的客户端应用程序不包括 ASP.Net Web 应用程序!
本文假设 URL: http://localhost/mywebservices/updownload.asmx
共有 4 个程序文件 (Web.Config 就不赘述了)
Server Side:
标题中所提到的 "异步" 其实在服务器端的程序并没有什么特殊的,而主要是通过客户端应用程序
异步调用相关 Web Method 实现的!
1. updownload.asmx ,位于 IIS 的某个 Web 共享目录,代码如下,只有一句话:
<%@ WebService Language="c#" Codebehind="UpDownLoad.asmx.cs" Class="Service1" %>
2. updownload.asmx.cs ,即: updownload.asmx 的 Codebehind ,位于 IIS 的某个 Web 共享目录的 bin 子目录下,代码如下:
/*
本文件位于 Web 共享目录的 bin 子目录下,通过执行如下命令行编译:
csc /t:library updownload.asmx.cs
*/
using System.Diagnostics;
using System.Web;
using System.Web.Services;
using System.IO;
using System;
public class Service1 : System.Web.Services.WebService
{
[WebMethod]
public string HelloWorld()
{
return "Hello World";
}
//从 Web Method 本身,其实看不出 "同步" 还是 "异步"
[WebMethod(Description = "为了支持多点分块异步上传文件,此方法必须由客户端预先调用,以便在服务器端生成指定 FileName 和 Length 大小的空白文件预定空间! 建议客户端同步调用")]
public string CreateBlankFile(string FileName,int Length) //建议由客户端同步调用
{
FileStream fs = new FileStream(Server.MapPath(".") + "\\" + FileName, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None);
fs.Write(new byte[Length], 0, Length);
fs.Close();
fs = null;
return FileName + " (" + Length + ") 空白文件已经创建!";
}
[WebMethod(Description = "提供一个用于一次完整上传整个文件的方法! 建议客户端同步调用")]
public string UploadFileBytes(byte[] Bytes,string FileName)
{
return UploadFileChunkBytes(Bytes, 0, FileName);
}
[WebMethod(Description = "提供一个用于一次只上传由 Position 位置起始的, Bytes 字节的 FileName 文件块存入服务器端相应文件的相应字节位置! 建议客户端异步调用")]
// 这里只要多提供一个 Position 参数,余下的再由客户端调用异步的该方法,就轻松达到目的了!
public string UploadFileChunkBytes(byte[] Bytes,int Position,string FileName)
{
try
{
FileStream fs = new FileStream(Server.MapPath(".") + "\\" + FileName, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite);
//该 Bytes 的字节要写到 服务器端 相应文件的从 Position 开始的字节
fs.Position = Position;
fs.Write(Bytes, 0, Bytes.Length);
fs.Close();
fs = null;
return FileName + " 文件块: 位置[" + Position + "," + (Position + Bytes.Length) + "] 大小(" + Bytes.Length + ") 上传成功!";
}
catch (Exception e)
{
return e.Message;
}
}
[WebMethod]
public byte[] DownloadFileBytes(string FileName)
{
if (File.Exists(FileName))
{
try
{
FileStream fs = File.OpenRead(FileName);
int i = (int) fs.Length;
byte[] ba = new byte[i];
fs.Read(ba,0,i);
fs.Close();
return ba;
}
catch
{
return new byte[0];
}
}
else
{
return new byte[0];
}
}
}
//=======================================================================
Client Side:
3. UpDownloadProxy.cs :
本文件由如下命令生成
% Visual Studio .Net 2003 安装目录下的 %\SDK\v1.1\Bin\wsdl.exe
具体命令行如下:
wsdl.exe /l:CS /out:UpDownloadProxy.cs http://localhost/MyWebServices/updownload.asmx?wsdl
生成的本地的客户端代理类代码里已经为每个 Web Method 生成了可异步和同步执行的方法,例如:
public string HelloWorld() {}
public System.IAsyncResult BeginHelloWorld(...) {}
public string EndHelloWorld(...) {}
下面是该命令行生成的完整的 UpDownloadProxy.cs 代码,就不修改了:
/*
通过执行如下命令行编译,生成 UpDownloadProxy.dll :
csc /t:library UpDownloadProxy.cs
*/
//------------------------------------------------------------------------------
// <autogenerated>
// This code was generated by a tool.
// Runtime Version: 1.1.4322.573
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </autogenerated>
//------------------------------------------------------------------------------
//
// 此源代码由 wsdl, Version=1.1.4322.573 自动生成。
//
using System.Diagnostics;
using System.Xml.Serialization;
using System;
using System.Web.Services.Protocols;
using System.ComponentModel;
using System.Web.Services;
/// <remarks/>
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Web.Services.WebServiceBindingAttribute(Name="Service1Soap", Namespace="http://tempuri.org/")]
public class Service1 : System.Web.Services.Protocols.SoapHttpClientProtocol {
/// <remarks/>
public Service1() {
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)]
public string HelloWorld() {
object[] results = this.Invoke("HelloWorld", new object[0]);
return ((string)(results[0]));
}
/// <remarks/>
public System.IAsyncResult BeginHelloWorld(System.AsyncCallback callback, object asyncState) {
return this.BeginInvoke("HelloWorld", new object[0], callback, asyncState);
}
/// <remarks/>
public string EndHelloWorld(System.IAsyncResult asyncResult) {
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)]
public string CreateBlankFile(string FileName, int Length) {
object[] results = this.Invoke("CreateBlankFile", new object[] {
FileName,
Length});
return ((string)(results[0]));
}
/// <remarks/>
public System.IAsyncResult BeginCreateBlankFile(string FileName, int Length, System.AsyncCallback callback, object asyncState) {
return this.BeginInvoke("CreateBlankFile", new object[] {
FileName,
Length}, callback, asyncState);
}
/// <remarks/>
public string EndCreateBlankFile(System.IAsyncResult asyncResult) {
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)]
public string UploadFileBytes([System.Xml.Serialization.XmlElementAttribute(DataType="base64Binary")] System.Byte[] Bytes, string FileName) {
object[] results = this.Invoke("UploadFileBytes", new object[] {
Bytes,
FileName});
return ((string)(results[0]));
}
/// <remarks/>
public System.IAsyncResult BeginUploadFileBytes(System.Byte[] Bytes, string FileName, System.AsyncCallback callback, object asyncState) {
return this.BeginInvoke("UploadFileBytes", new object[] {
Bytes,
FileName}, callback, asyncState);
}
/// <remarks/>
public string EndUploadFileBytes(System.IAsyncResult asyncResult) {
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)]
public string UploadFileChunkBytes([System.Xml.Serialization.XmlElementAttribute(DataType="base64Binary")] System.Byte[] Bytes, int Position, string FileName) {
object[] results = this.Invoke("UploadFileChunkBytes", new object[] {
Bytes,
Position,
FileName});
return ((string)(results[0]));
}
/// <remarks/>
public System.IAsyncResult BeginUploadFileChunkBytes(System.Byte[] Bytes, int Position, string FileName, System.AsyncCallback callback, object asyncState) {
return this.BeginInvoke("UploadFileChunkBytes", new object[] {
Bytes,
Position,
FileName}, callback, asyncState);
}
/// <remarks/>
public string EndUploadFileChunkBytes(System.IAsyncResult asyncResult) {
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")]
public System.Byte[] DownloadFileBytes(string FileName) {
object[] results = this.Invoke("DownloadFileBytes", new object[] {
FileName});
return ((System.Byte[])(results[0]));
}
/// <remarks/>
public System.IAsyncResult BeginDownloadFileBytes(string FileName, System.AsyncCallback callback, object asyncState) {
return this.BeginInvoke("DownloadFileBytes", new object[] {
FileName}, callback, asyncState);
}
/// <remarks/>
public System.Byte[] EndDownloadFileBytes(System.IAsyncResult asyncResult) {
object[] results = this.EndInvoke(asyncResult);
return ((System.Byte[])(results[0]));
}
}
//=======================================================================
4. UpDownloadClient.cs :
该程序才是真正实现文件分块多点异步上传的核心代码:
/*
通过执行如下命令行编译:
csc updownloadClient.cs /r:updownloadproxy.dll
*/
using System;
using System.IO;
public class Class1
{
static void Main(string[] args)
{
//Download(ServerSidepath, ClientSidePath)
Download(@"e:\test.jpg", @"f:\test_local.jpg");
System.Console.WriteLine("down End");
System.Console.WriteLine("同步 up file exec ...");
UploadFile(@"e:\Northwind.mdb");
System.Console.WriteLine("同步 up file End\n");
System.Console.WriteLine("异步 up chunks exec ...");
UploadFileChunks(@"e:\test.rar", 64);
System.Console.ReadLine();
}
public static void UploadFile(string LocalFileName)
{
Service1 xx = new Service1();
FileStream fs = new FileStream(LocalFileName, FileMode.Open); //Client Side Path
byte[] buffer = new byte[fs.Length];
fs.Read(buffer, 0, buffer.Length);
//调用 "同步执行" 的本地 Web Sevices 代理类的 方法,相当于同步调用了 Web Method !
xx.UploadFileBytes(buffer, System.IO.Path.GetFileName(LocalFileName));
}
//指定要上传的本地文件的路径,及每次上传文件块的大小
public static void UploadFileChunks(string LocalFileName,int ChunkSize)
{
Service1 xx = new Service1();
string filename = System.IO.Path.GetFileName(LocalFileName);
FileStream fs = new FileStream(LocalFileName, FileMode.Open); //Client Side Path
//fs = File.OpenRead(LocalFileName);
int r = (int) fs.Length; //用于记录剩余还未上传的字节数,初值是文件的大小
//调用 "同步执行" 的本地 Web Sevices 代理类的 方法,相当于同步调用了 Web Method !
//预定服务器端空间
xx.CreateBlankFile(filename,r);
int size = ChunkSize * 1024;
int k = 0; //用于记录已经上传的字节数
i++; //用于记录上传的文件块数
while (r >= size)
{
byte[] buffer = new byte[size];
fs.Read(buffer,0,buffer.Length);
//调用 "异步执行" 的本地 Web Sevices 代理类的 方法,相当于异步调用了 Web Method !
//该 buffer 的字节要写到 服务器端 相应文件的从 Position = k 开始的字节
xx.BeginUploadFileChunkBytes(buffer,k,filename,new AsyncCallback(UploadFileChunkCallback),xx);
k += size;
r -= size;
i++;
}
if (r > 0) //剩余的零头
{
byte[] buffer = new byte[r];
fs.Read(buffer,0,buffer.Length);
//调用 "异步执行" 的本地 Web Sevices 代理类的 方法,相当于异步调用了 Web Method !
//该 buffer 的字节要写到 服务器端 相应文件的从 Position = k 开始的字节
xx.BeginUploadFileChunkBytes(buffer,k,filename,new AsyncCallback(UploadFileChunkCallback),xx);
i++;
}
fs.Close();
}
private static int i = -1; //用于记录上传的文件块数
private static void UploadFileChunkCallback(IAsyncResult ar)
{
Service1 x = (Service1) ar.AsyncState;
Console.WriteLine(x.EndUploadFileChunkBytes(ar));
if ( --i == 0)
{
Console.WriteLine("异步 up all chunks end");
}
}
public static void Download(string ServerSideFileName,string LocalFileName)
{
Service1 xx = new Service1();
byte[] ba = xx.DownloadFileBytes(ServerSideFileName); //Server Side Path
FileStream fs = new FileStream(LocalFileName, FileMode.Create); //Client Side Path
fs.Write(ba,0,ba.Length);
fs.Close();
}
}
//===========================================================================
至此我们通过纯手工的方式完成了任务,之所以不用 VS 就是为了让码子简洁明了!
Microshaoft .Night 就是这么平易近人! (PMPMP to MS)
通过 Web Sevices 上传文件非常简单,甚至比传统的 http Web 上传还简单!
同时较轻松地就实现了文件分块多点异步上传:
Server 端代码没啥特殊的!
Client 端代码稍微复杂些!
本文假设 URL: http://localhost/mywebservices/updownload.asmx
共有 4 个程序文件 (Web.Config 就不赘述了)
Server Side:
标题中所提到的 "异步" 其实在服务器端的程序并没有什么特殊的,而主要是通过客户端应用程序
异步调用相关 Web Method 实现的!
1. updownload.asmx ,位于 IIS 的某个 Web 共享目录,代码如下,只有一句话:
<%@ WebService Language="c#" Codebehind="UpDownLoad.asmx.cs" Class="Service1" %>
2. updownload.asmx.cs ,即: updownload.asmx 的 Codebehind ,位于 IIS 的某个 Web 共享目录的 bin 子目录下,代码如下:
/*
本文件位于 Web 共享目录的 bin 子目录下,通过执行如下命令行编译:
csc /t:library updownload.asmx.cs
*/
using System.Diagnostics;
using System.Web;
using System.Web.Services;
using System.IO;
using System;
public class Service1 : System.Web.Services.WebService
{
[WebMethod]
public string HelloWorld()
{
return "Hello World";
}
//从 Web Method 本身,其实看不出 "同步" 还是 "异步"
[WebMethod(Description = "为了支持多点分块异步上传文件,此方法必须由客户端预先调用,以便在服务器端生成指定 FileName 和 Length 大小的空白文件预定空间! 建议客户端同步调用")]
public string CreateBlankFile(string FileName,int Length) //建议由客户端同步调用
{
FileStream fs = new FileStream(Server.MapPath(".") + "\\" + FileName, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None);
fs.Write(new byte[Length], 0, Length);
fs.Close();
fs = null;
return FileName + " (" + Length + ") 空白文件已经创建!";
}
[WebMethod(Description = "提供一个用于一次完整上传整个文件的方法! 建议客户端同步调用")]
public string UploadFileBytes(byte[] Bytes,string FileName)
{
return UploadFileChunkBytes(Bytes, 0, FileName);
}
[WebMethod(Description = "提供一个用于一次只上传由 Position 位置起始的, Bytes 字节的 FileName 文件块存入服务器端相应文件的相应字节位置! 建议客户端异步调用")]
// 这里只要多提供一个 Position 参数,余下的再由客户端调用异步的该方法,就轻松达到目的了!
public string UploadFileChunkBytes(byte[] Bytes,int Position,string FileName)
{
try
{
FileStream fs = new FileStream(Server.MapPath(".") + "\\" + FileName, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite);
//该 Bytes 的字节要写到 服务器端 相应文件的从 Position 开始的字节
fs.Position = Position;
fs.Write(Bytes, 0, Bytes.Length);
fs.Close();
fs = null;
return FileName + " 文件块: 位置[" + Position + "," + (Position + Bytes.Length) + "] 大小(" + Bytes.Length + ") 上传成功!";
}
catch (Exception e)
{
return e.Message;
}
}
[WebMethod]
public byte[] DownloadFileBytes(string FileName)
{
if (File.Exists(FileName))
{
try
{
FileStream fs = File.OpenRead(FileName);
int i = (int) fs.Length;
byte[] ba = new byte[i];
fs.Read(ba,0,i);
fs.Close();
return ba;
}
catch
{
return new byte[0];
}
}
else
{
return new byte[0];
}
}
}
//=======================================================================
Client Side:
3. UpDownloadProxy.cs :
本文件由如下命令生成
% Visual Studio .Net 2003 安装目录下的 %\SDK\v1.1\Bin\wsdl.exe
具体命令行如下:
wsdl.exe /l:CS /out:UpDownloadProxy.cs http://localhost/MyWebServices/updownload.asmx?wsdl
生成的本地的客户端代理类代码里已经为每个 Web Method 生成了可异步和同步执行的方法,例如:
public string HelloWorld() {}
public System.IAsyncResult BeginHelloWorld(...) {}
public string EndHelloWorld(...) {}
下面是该命令行生成的完整的 UpDownloadProxy.cs 代码,就不修改了:
/*
通过执行如下命令行编译,生成 UpDownloadProxy.dll :
csc /t:library UpDownloadProxy.cs
*/
//------------------------------------------------------------------------------
// <autogenerated>
// This code was generated by a tool.
// Runtime Version: 1.1.4322.573
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </autogenerated>
//------------------------------------------------------------------------------
//
// 此源代码由 wsdl, Version=1.1.4322.573 自动生成。
//
using System.Diagnostics;
using System.Xml.Serialization;
using System;
using System.Web.Services.Protocols;
using System.ComponentModel;
using System.Web.Services;
/// <remarks/>
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Web.Services.WebServiceBindingAttribute(Name="Service1Soap", Namespace="http://tempuri.org/")]
public class Service1 : System.Web.Services.Protocols.SoapHttpClientProtocol {
/// <remarks/>
public Service1() {
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)]
public string HelloWorld() {
object[] results = this.Invoke("HelloWorld", new object[0]);
return ((string)(results[0]));
}
/// <remarks/>
public System.IAsyncResult BeginHelloWorld(System.AsyncCallback callback, object asyncState) {
return this.BeginInvoke("HelloWorld", new object[0], callback, asyncState);
}
/// <remarks/>
public string EndHelloWorld(System.IAsyncResult asyncResult) {
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)]
public string CreateBlankFile(string FileName, int Length) {
object[] results = this.Invoke("CreateBlankFile", new object[] {
FileName,
Length});
return ((string)(results[0]));
}
/// <remarks/>
public System.IAsyncResult BeginCreateBlankFile(string FileName, int Length, System.AsyncCallback callback, object asyncState) {
return this.BeginInvoke("CreateBlankFile", new object[] {
FileName,
Length}, callback, asyncState);
}
/// <remarks/>
public string EndCreateBlankFile(System.IAsyncResult asyncResult) {
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)]
public string UploadFileBytes([System.Xml.Serialization.XmlElementAttribute(DataType="base64Binary")] System.Byte[] Bytes, string FileName) {
object[] results = this.Invoke("UploadFileBytes", new object[] {
Bytes,
FileName});
return ((string)(results[0]));
}
/// <remarks/>
public System.IAsyncResult BeginUploadFileBytes(System.Byte[] Bytes, string FileName, System.AsyncCallback callback, object asyncState) {
return this.BeginInvoke("UploadFileBytes", new object[] {
Bytes,
FileName}, callback, asyncState);
}
/// <remarks/>
public string EndUploadFileBytes(System.IAsyncResult asyncResult) {
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)]
public string UploadFileChunkBytes([System.Xml.Serialization.XmlElementAttribute(DataType="base64Binary")] System.Byte[] Bytes, int Position, string FileName) {
object[] results = this.Invoke("UploadFileChunkBytes", new object[] {
Bytes,
Position,
FileName});
return ((string)(results[0]));
}
/// <remarks/>
public System.IAsyncResult BeginUploadFileChunkBytes(System.Byte[] Bytes, int Position, string FileName, System.AsyncCallback callback, object asyncState) {
return this.BeginInvoke("UploadFileChunkBytes", new object[] {
Bytes,
Position,
FileName}, callback, asyncState);
}
/// <remarks/>
public string EndUploadFileChunkBytes(System.IAsyncResult asyncResult) {
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")]
public System.Byte[] DownloadFileBytes(string FileName) {
object[] results = this.Invoke("DownloadFileBytes", new object[] {
FileName});
return ((System.Byte[])(results[0]));
}
/// <remarks/>
public System.IAsyncResult BeginDownloadFileBytes(string FileName, System.AsyncCallback callback, object asyncState) {
return this.BeginInvoke("DownloadFileBytes", new object[] {
FileName}, callback, asyncState);
}
/// <remarks/>
public System.Byte[] EndDownloadFileBytes(System.IAsyncResult asyncResult) {
object[] results = this.EndInvoke(asyncResult);
return ((System.Byte[])(results[0]));
}
}
//=======================================================================
4. UpDownloadClient.cs :
该程序才是真正实现文件分块多点异步上传的核心代码:
/*
通过执行如下命令行编译:
csc updownloadClient.cs /r:updownloadproxy.dll
*/
using System;
using System.IO;
public class Class1
{
static void Main(string[] args)
{
//Download(ServerSidepath, ClientSidePath)
Download(@"e:\test.jpg", @"f:\test_local.jpg");
System.Console.WriteLine("down End");
System.Console.WriteLine("同步 up file exec ...");
UploadFile(@"e:\Northwind.mdb");
System.Console.WriteLine("同步 up file End\n");
System.Console.WriteLine("异步 up chunks exec ...");
UploadFileChunks(@"e:\test.rar", 64);
System.Console.ReadLine();
}
public static void UploadFile(string LocalFileName)
{
Service1 xx = new Service1();
FileStream fs = new FileStream(LocalFileName, FileMode.Open); //Client Side Path
byte[] buffer = new byte[fs.Length];
fs.Read(buffer, 0, buffer.Length);
//调用 "同步执行" 的本地 Web Sevices 代理类的 方法,相当于同步调用了 Web Method !
xx.UploadFileBytes(buffer, System.IO.Path.GetFileName(LocalFileName));
}
//指定要上传的本地文件的路径,及每次上传文件块的大小
public static void UploadFileChunks(string LocalFileName,int ChunkSize)
{
Service1 xx = new Service1();
string filename = System.IO.Path.GetFileName(LocalFileName);
FileStream fs = new FileStream(LocalFileName, FileMode.Open); //Client Side Path
//fs = File.OpenRead(LocalFileName);
int r = (int) fs.Length; //用于记录剩余还未上传的字节数,初值是文件的大小
//调用 "同步执行" 的本地 Web Sevices 代理类的 方法,相当于同步调用了 Web Method !
//预定服务器端空间
xx.CreateBlankFile(filename,r);
int size = ChunkSize * 1024;
int k = 0; //用于记录已经上传的字节数
i++; //用于记录上传的文件块数
while (r >= size)
{
byte[] buffer = new byte[size];
fs.Read(buffer,0,buffer.Length);
//调用 "异步执行" 的本地 Web Sevices 代理类的 方法,相当于异步调用了 Web Method !
//该 buffer 的字节要写到 服务器端 相应文件的从 Position = k 开始的字节
xx.BeginUploadFileChunkBytes(buffer,k,filename,new AsyncCallback(UploadFileChunkCallback),xx);
k += size;
r -= size;
i++;
}
if (r > 0) //剩余的零头
{
byte[] buffer = new byte[r];
fs.Read(buffer,0,buffer.Length);
//调用 "异步执行" 的本地 Web Sevices 代理类的 方法,相当于异步调用了 Web Method !
//该 buffer 的字节要写到 服务器端 相应文件的从 Position = k 开始的字节
xx.BeginUploadFileChunkBytes(buffer,k,filename,new AsyncCallback(UploadFileChunkCallback),xx);
i++;
}
fs.Close();
}
private static int i = -1; //用于记录上传的文件块数
private static void UploadFileChunkCallback(IAsyncResult ar)
{
Service1 x = (Service1) ar.AsyncState;
Console.WriteLine(x.EndUploadFileChunkBytes(ar));
if ( --i == 0)
{
Console.WriteLine("异步 up all chunks end");
}
}
public static void Download(string ServerSideFileName,string LocalFileName)
{
Service1 xx = new Service1();
byte[] ba = xx.DownloadFileBytes(ServerSideFileName); //Server Side Path
FileStream fs = new FileStream(LocalFileName, FileMode.Create); //Client Side Path
fs.Write(ba,0,ba.Length);
fs.Close();
}
}
//===========================================================================
至此我们通过纯手工的方式完成了任务,之所以不用 VS 就是为了让码子简洁明了!
Microshaoft .Night 就是这么平易近人! (PMPMP to MS)
通过 Web Sevices 上传文件非常简单,甚至比传统的 http Web 上传还简单!
同时较轻松地就实现了文件分块多点异步上传:
Server 端代码没啥特殊的!
Client 端代码稍微复杂些!
无为清净楼资源网 Design By www.qnjia.com
广告合作:本站广告合作请联系QQ:858582 申请时备注:广告合作(否则不回)
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
无为清净楼资源网 Design By www.qnjia.com
暂无评论...
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。
更新日志
2024年11月17日
2024年11月17日
- 中国武警男声合唱团《辉煌之声1天路》[DTS-WAV分轨]
- 紫薇《旧曲新韵》[320K/MP3][175.29MB]
- 紫薇《旧曲新韵》[FLAC/分轨][550.18MB]
- 周深《反深代词》[先听版][320K/MP3][72.71MB]
- 李佳薇.2024-会发光的【黑籁音乐】【FLAC分轨】
- 后弦.2012-很有爱【天浩盛世】【WAV+CUE】
- 林俊吉.2012-将你惜命命【美华】【WAV+CUE】
- 晓雅《分享》DTS-WAV
- 黑鸭子2008-飞歌[首版][WAV+CUE]
- 黄乙玲1989-水泼落地难收回[日本天龙版][WAV+CUE]
- 周深《反深代词》[先听版][FLAC/分轨][310.97MB]
- 姜育恒1984《什么时候·串起又散落》台湾复刻版[WAV+CUE][1G]
- 那英《如今》引进版[WAV+CUE][1G]
- 蔡幸娟.1991-真的让我爱你吗【飞碟】【WAV+CUE】
- 群星.2024-好团圆电视剧原声带【TME】【FLAC分轨】