人人做人人澡人人爽欧美,国产主播一区二区,久久久精品五月天,羞羞视频在线观看免费

當(dāng)前位置:蘿卜系統(tǒng)下載站 > 技術(shù)開(kāi)發(fā)教程 > 詳細(xì)頁(yè)面

運(yùn)用基本類庫(kù)  -- zt 統(tǒng)一教學(xué)網(wǎng)

運(yùn)用基本類庫(kù) -- zt 統(tǒng)一教學(xué)網(wǎng)

更新時(shí)間:2022-06-07 文章作者:未知 信息來(lái)源:網(wǎng)絡(luò) 閱讀次數(shù):

使用基本類庫(kù)


為了更好地理解C#與C++的區(qū)別和解決問(wèn)題方式的變化,我們先來(lái)看一個(gè)比較簡(jiǎn)單的例子。我們將創(chuàng)建一個(gè)讀取文本文件的類,并在屏幕上顯示其內(nèi)容。我將把它做成多線程程序,以便在從磁盤(pán)上讀取數(shù)據(jù)時(shí)還可以做其他的工作。

在C++中,我們可能會(huì)創(chuàng)建一個(gè)讀文件的線程和另一個(gè)做其他工作的線程,這二個(gè)線程將各自獨(dú)立地運(yùn)行,但可能會(huì)需要對(duì)它們進(jìn)行同步。在C#中,我們也可以完成同樣的工作,由于.NET框架提供了功能強(qiáng)大的異步I/O機(jī)制,在編寫(xiě)線程時(shí),我們會(huì)節(jié)省不少的時(shí)間。

異步I/O支持是內(nèi)置在CLR中的,而且?guī)缀跖c使用正常的I/O流類一樣簡(jiǎn)單。在程序的開(kāi)始,我們首先通知編譯器,我們將在程序中使用許多名字空間中的對(duì)象:

usingSystem;
usingSystem.IO;
usingSystem.Text;

在程序中包含System,并不會(huì)自動(dòng)地包含其所有的子名字空間,必須使用using關(guān)健字明確地包含每個(gè)子名字空間。我們?cè)诶又袝?huì)用到I/O流類,因此需要包含System.IO名字空間,我們還需要System.Text名字空間支持字節(jié)流的ASCII編碼。

由于.NET架構(gòu)為完成了大部分的工作,編寫(xiě)這一程序所需的步驟相當(dāng)簡(jiǎn)單。我們將用到Stream類的BeginRead方法,它提供異步I/O功能,將數(shù)據(jù)讀入到一個(gè)緩沖區(qū)中,當(dāng)緩沖區(qū)可以處理時(shí)調(diào)用相應(yīng)的處理程序。

我們需要使用一個(gè)字節(jié)數(shù)組作為緩沖區(qū)和回叫方法的代理,并將這二者定義為驅(qū)動(dòng)程序類的private成員變量。

publicclassAsynchIOTester
{
privateStreaminputStream;
privatebyte[]buffer;
privateAsyncCallbackmyCallBack;

inputStream是一個(gè)Stream類型的變量,我們將對(duì)它調(diào)用BeginRead方法。代理與成員函數(shù)的指針?lè)浅O嗨啤4硎荂#的第一類元素。

當(dāng)緩沖區(qū)被磁盤(pán)上的文件填滿時(shí),.NET將調(diào)用被代理的方法對(duì)數(shù)據(jù)進(jìn)行處理。在等待讀取數(shù)據(jù)期間,我們可以讓計(jì)算機(jī)完成其他的工作。(在本例中是將1個(gè)整型變量由1增加到50000,但在實(shí)際的應(yīng)用程序中,我們可以讓計(jì)算機(jī)與用戶進(jìn)行交互或作其他有意義的工作。)

本例中的代理被定義為AsyncCallback類型的過(guò)程,這是Stream的BeginRead方法所需要的。System空間中AsyncCallback類型代理的定義如下所示:

publicdelegatevoidAsyncCallback(IAsyncResultar);

這一代理可以是與任何返回void類型值、將IAsyncResult界面作為參數(shù)的方法相關(guān)聯(lián)的。在該方法被調(diào)用時(shí),CLR可以在運(yùn)行時(shí)傳遞IAsyncResult界面對(duì)象作為參數(shù)。我們需要如下所示的形式定義該方法:

voidOnCompletedRead(IAsyncResultasyncResult)

然后在構(gòu)造器中與代理連接起來(lái):

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

上面的代碼將代理的實(shí)例賦給成員變量myCallback。下面是全部程序的詳細(xì)工作原理。在Main函數(shù)中,創(chuàng)建了一個(gè)類的實(shí)例,并讓它開(kāi)始運(yùn)行:

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

new關(guān)健字能夠啟動(dòng)構(gòu)造器。在構(gòu)造器中我們打開(kāi)一個(gè)文件,并得到一個(gè)Stream對(duì)象。然后在緩沖中分配空間并與回調(diào)機(jī)制聯(lián)結(jié)起來(lái)。

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

在Run方法中,我們調(diào)用了BeginRead,它將以異步的方式讀取文件。

inputStream.BeginRead(
buffer,//存放結(jié)果
0,//偏移量
buffer.Length,//緩沖區(qū)中有多少字節(jié)
myCallBack,//回調(diào)代理
null);//本地對(duì)象

這時(shí),我們可以完成其他的工作。

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

文件讀取操作結(jié)束后,CLR將調(diào)用回調(diào)方法。

voidOnCompletedRead(IAsyncResultasyncResult)
{

在OnCompletedRead中要做的第一件事就是通過(guò)調(diào)用Stream對(duì)象的EndRead方法找出讀取了多少字節(jié):

intbytesRead=inputStream.EndRead(asyncResult);

對(duì)EndRead的調(diào)用將返回讀取的字節(jié)數(shù)。如果返回的數(shù)字比0大,則將緩沖區(qū)轉(zhuǎn)換為一個(gè)字符串,然后將它寫(xiě)到控制臺(tái)上,然后再次調(diào)用BeginRead,開(kāi)始另一次異步讀的過(guò)程。

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

現(xiàn)在,在讀取文件的過(guò)程中就可以作別的工作了(在本例中是從1數(shù)到50000),但我們可以在每次緩沖區(qū)滿了時(shí)對(duì)讀取的數(shù)據(jù)進(jìn)行處理(在本例中是向控制臺(tái)輸出緩沖區(qū)中的數(shù)據(jù))。有興趣的讀者可以點(diǎn)擊此處下載完整的源代碼。

異步I/O的管理完全是由CLR提供的,這樣,在網(wǎng)絡(luò)上讀取文件時(shí),會(huì)更好些。



在網(wǎng)絡(luò)上讀取文件


在C++中,在網(wǎng)絡(luò)上讀取文件需要有相當(dāng)?shù)木幊碳记桑?NET對(duì)此提供了廣泛的支持。事實(shí)上,在網(wǎng)絡(luò)上讀取文件僅僅是基礎(chǔ)類庫(kù)中Stream類的另一種應(yīng)用。

首先,為了對(duì)TCP/IP端口(在本例中是65000)進(jìn)行監(jiān)聽(tīng),我們需要?jiǎng)?chuàng)建一個(gè)TCPListener類的實(shí)例。

TCPListenertcpListener=newTCPListener(65000);

一旦創(chuàng)建后,就讓它開(kāi)始進(jìn)行監(jiān)聽(tīng)。

tcpListener.Start();

現(xiàn)在就要等待客戶連接的要求了。

SocketsocketForClient=tcpListener.Accept();

TCPListener對(duì)象的Accept方法返回一個(gè)Socket對(duì)象,Accept是一個(gè)同步的方法,除非接收到一個(gè)連接請(qǐng)求它才會(huì)返回。如果連接成功,就可以開(kāi)始向客戶發(fā)送文件了。

if(socketForClient.Connected)
{
???


接下來(lái),我們需要?jiǎng)?chuàng)建一個(gè)NetworkStream類,將報(bào)路傳遞給constructor:

NetworkStreamnetworkStream=newNetworkStream(socketForClient);

然后創(chuàng)建一個(gè)StreamWriter對(duì)象,只是這次不是在文件上而是在剛才創(chuàng)建的NetworkStream類上創(chuàng)建該對(duì)象:

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

當(dāng)向該流寫(xiě)內(nèi)容時(shí),流就通過(guò)網(wǎng)絡(luò)被傳輸給客戶端。



客戶端的創(chuàng)建


客戶端軟件就是一個(gè)TCPClient類的具體例子,TCPClient類代表連向主機(jī)的一個(gè)TCP/IP連接。

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

有了TCPClient對(duì)象后,我們就可以創(chuàng)建NetworkStream對(duì)象了,然后在其上創(chuàng)建StreamReader類:

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

現(xiàn)在,只要其中有數(shù)據(jù)就讀取該流,并將結(jié)果輸出到控制臺(tái)上。

do
{
outputString=streamReader.ReadLine();

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

為了對(duì)這一段代碼進(jìn)行測(cè)試,可以創(chuàng)建如下一個(gè)測(cè)試用的文件:

Thisislineone
Thisislinetwo
Thisislinethree
Thisislinefour

這是來(lái)自服務(wù)器的輸出:

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

下面是來(lái)自客戶端的輸出:

Thisislineone
Thisislinetwo
Thisislinethree
Thisislinefour 

溫馨提示:喜歡本站的話,請(qǐng)收藏一下本站!

本類教程下載

系統(tǒng)下載排行

網(wǎng)站地圖xml | 網(wǎng)站地圖html
主站蜘蛛池模板: 连城县| 布尔津县| 眉山市| 乌鲁木齐市| 突泉县| 宜川县| 汝城县| 万荣县| 凤翔县| 尼玛县| 习水县| 通渭县| 酒泉市| 慈利县| 达尔| 金门县| 固原市| 伽师县| 永宁县| 图片| 白银市| 赤壁市| 滦平县| 田东县| 田林县| 大方县| 青浦区| 南康市| 淮北市| 敦化市| 开远市| 泸州市| 平定县| 团风县| 威海市| 五大连池市| 金沙县| 蒲江县| 开远市| 文水县| 读书|