庞大资源库的计算机教程网站!
设为首页
加入收藏
总编信箱
投稿或申请专栏请先 [登 陆]
首页 操作系统 程序设计 图形图像 媒体动画 机械电子 WEB开发 数 据 库 办公系列 路由技术 网络原理 网络应用
认证考试 安全技术
首页>WEB开发>ASP.NET>.NET Framework>正文
资料搜索
Google搜索
Google
返回上级列表

推荐文章

快速保存网页中所有图片的方法
Windows中让光驱巧妙“隐身”技
防范非法用户入侵Win 2000/XP系
两款比较典型的ASP木马防范方法
有关表格边框的css语法整理
Windows XP中可以被禁用的服务
SQL Server导出导入数据方法
Javascript所有对象的属性的获
网页(HTML)中的特殊字符
与篮球共舞,尽显模式本色
QQ病毒的手工清除方法
Photoshop为极品美女打造性感睫
天衣无缝:IIS与PHP水火也相容
SQL Server存储过程编写和优化

使用基本类库

 作者:本站收集   日期:2005-3-17
字号选择〖 〗/ 双击滚屏 单击停止   


为了更好地理解C#与C++的区别和解决问题方式的变化,我们先来看一个比较简单的例子。我们将创建一个读取文本文件的类,并在屏幕上显示其内容。我将把它做成多线程程序,以便在从磁盘上读取数据时还可以做其他的工作。

在C++中,我们可能会创建一个读文件的线程和另一个做其他工作的线程,这二个线程将各自独立地运行,但可能会需要对它们进行同步。在C#中,我们也可以完成同样的工作,由于.NET框架提供了功能强大的异步I/O机制,在编写线程时,我们会节省不少的时间。

异步I/O支持是内置在CLR中的,而且几乎与使用正常的I/O流类一样简单。在程序的开始,我们首先通知编译器,我们将在程序中使用许多名字空间中的对象:

usingSystem;
usingSystem.IO;
usingSystem.Text;

在程序中包含System,并不会自动地包含其所有的子名字空间,必须使用using关健字明确地包含每个子名字空间。我们在例子中会用到I/O流类,因此需要包含System.IO名字空间,我们还需要System.Text名字空间支持字节流的ASCII编码。

由于.NET架构为完成了大部分的工作,编写这一程序所需的步骤相当简单。我们将用到Stream类的BeginRead方法,它提供异步I/O功能,将数据读入到一个缓冲区中,当缓冲区可以处理时调用相应的处理程序。

我们需要使用一个字节数组作为缓冲区和回叫方法的代理,并将这二者定义为驱动程序类的private成员变量。

publicclassAsynchIOTester
{
privateStreaminputStream;
privatebyte[]buffer;
privateAsyncCallbackmyCallBack;

inputStream是一个Stream类型的变量,我们将对它调用BeginRead方法。代理与成员函数的指针非常相似。代理是C#的第一类元素。

当缓冲区被磁盘上的文件填满时,.NET将调用被代理的方法对数据进行处理。在等待读取数据期间,我们可以让计算机完成其他的工作。(在本例中是将1个整型变量由1增加到50000,但在实际的应用程序中,我们可以让计算机与用户进行交互或作其他有意义的工作。)

本例中的代理被定义为AsyncCallback类型的过程,这是Stream的BeginRead方法所需要的。System空间中AsyncCallback类型代理的定义如下所示:

publicdelegatevoidAsyncCallback(IAsyncResultar);

这一代理可以是与任何返回void类型值、将IAsyncResult界面作为参数的方法相关联的。在该方法被调用时,CLR可以在运行时传递IAsyncResult界面对象作为参数。我们需要如下所示的形式定义该方法:

voidOnCompletedRead(IAsyncResultasyncResult)

然后在构造器中与代理连接起来:

AsynchIOTester()
{
???
myCallBack=newAsyncCallback(this.OnCompletedRead);
}

上面的代码将代理的实例赋给成员变量myCallback。下面是全部程序的详细工作原理。在Main函数中,创建了一个类的实例,并让它开始运行:

publicstaticvoidMain()
{
AsynchIOTestertheApp=newAsynchIOTester();
theApp.Run();
}

new关健字能够启动构造器。在构造器中我们打开一个文件,并得到一个Stream对象。然后在缓冲中分配空间并与回调机制联结起来。

AsynchIOTester()
{
inputStream=File.OpenRead(@"C:\MSDN\fromCppToCS.txt");
buffer=newbyte[BUFFER_SIZE];
myCallBack=newAsyncCallback(this.OnCompletedRead);
}

在Run方法中,我们调用了BeginRead,它将以异步的方式读取文件。

inputStream.BeginRead(
buffer,//存放结果
0,//偏移量
buffer.Length,//缓冲区中有多少字节
myCallBack,//回调代理
null);//本地对象

这时,我们可以完成其他的工作。

for(longi=0;i<50000;i++)
{
if(i%1000==0)
{
Console.WriteLine("i:{0}",i);
}
}

文件读取操作结束后,CLR将调用回调方法。

voidOnCompletedRead(IAsyncResultasyncResult)
{

在OnCompletedRead中要做的第一件事就是通过调用Stream对象的EndRead方法找出读取了多少字节:

intbytesRead=inputStream.EndRead(asyncResult);

对EndRead的调用将返回读取的字节数。如果返回的数字比0大,则将缓冲区转换为一个字符串,然后将它写到控制台上,然后再次调用BeginRead,开始另一次异步读的过程。

if(bytesRead>0)
{
Strings=Encoding.ASCII.GetString(buffer,0,bytesRead);
Console.WriteLine(s);
inputStream.BeginRead(buffer,0,buffer.Length,
myCallBack,null);
}

现在,在读取文件的过程中就可以作别的工作了(在本例中是从1数到50000),但我们可以在每次缓冲区满了时对读取的数据进行处理(在本例中是向控制台输出缓冲区中的数据)。有兴趣的读者可以点击此处下载完整的源代码。

异步I/O的管理完全是由CLR提供的,这样,在网络上读取文件时,会更好些。

 

在网络上读取文件

在C++中,在网络上读取文件需要有相当的编程技巧,.NET对此提供了广泛的支持。事实上,在网络上读取文件仅仅是基础类库中Stream类的另一种应用。

首先,为了对TCP/IP端口(在本例中是65000)进行监听,我们需要创建一个TCPListener类的实例。

TCPListenertcpListener=newTCPListener(65000);

一旦创建后,就让它开始进行监听。

tcpListener.Start();

现在就要等待客户连接的要求了。

SocketsocketForClient=tcpListener.Accept();

TCPListener对象的Accept方法返回一个Socket对象,Accept是一个同步的方法,除非接收到一个连接请求它才会返回。如果连接成功,就可以开始向客户发送文件了。

if(socketForClient.Connected)
{
???

接下来,我们需要创建一个NetworkStream类,将报路传递给constructor:

NetworkStreamnetworkStream=newNetworkStream(socketForClient);

然后创建一个StreamWriter对象,只是这次不是在文件上而是在刚才创建的NetworkStream类上创建该对象:

System.IO.StreamWriterstreamWriter=
newSystem.IO.StreamWriter(networkStream);

当向该流写内容时,流就通过网络被传输给客户端。

 

客户端的创建

客户端软件就是一个TCPClient类的具体例子,TCPClient类代表连向主机的一个TCP/IP连接。

TCPClientsocketForServer;
socketForServer=newTCPClient("localHost",65000);

有了TCPClient对象后,我们就可以创建NetworkStream对象了,然后在其上创建StreamReader类:

NetworkStreamnetworkStream=socketForServer.GetStream();
System.IO.StreamReaderstreamReader=
newSystem.IO.StreamReader(networkStream);

现在,只要其中有数据就读取该流,并将结果输出到控制台上。

do
{
outputString=streamReader.ReadLine();

if(outputString!=null)
{
Console.WriteLine(outputString);
}
}
while(outputString!=null);

为了对这一段代码进行测试,可以创建如下一个测试用的文件:

Thisislineone
Thisislinetwo
Thisislinethree
Thisislinefour

这是来自服务器的输出:

Output(Server)
Clientconnected
SendingThisislineone
SendingThisislinetwo
SendingThisislinethree
SendingThisislinefour
Disconnectingfromclient...
Exiting...

下面是来自客户端的输出:

Thisislineone
Thisislinetwo
Thisislinethree
Thisislinefour

上一篇:没有了    下一篇:类型映射  
[发送给好友]  [关闭窗口]  [返回顶部]   转载请注明来源:www.it00.com   
特别声明: 本站除部分特别声明禁止转载的专稿外的其他文章可以自由转载,但请务必注明出处和原始作者。文章版权归文章原始作者所有。对于被本站转载文章的个人和网站,我们表示深深的谢意。如果本站转载的文章有版权问题请联系编辑人员,我们尽快予以更正。
责任编辑: 原点 投稿作者: 本站收集
信息来源: 网络 录入时间: 2005-3-17
关于我们 - 广告服务 - 版权申明 - 网站地图 - 联系方式 - 总编信箱 - 会员投稿