对Stresram读写时序要先后用到两种读取方式怎么办?

当前位置: →
→ 实战Decorator模式:封装stream,在读写stream时提供事件通知
实战Decorator模式:封装stream,在读写stream时提供事件通知
& 作者及来源: Peanut - 博客园 &
&收藏到→_→:
摘要: 实战Decorator模式:封装stream,在读写stream时提供事件通知
"实战Decorator模式:封装stream,在读写stream时提供事件通知"::
&&& 前阵子的工作涉及一些,使用了面向流的方式做传输数据。在代码过程中,遇到一个新需求就是要统计流量。其实最简单的办法就时在读写流的地方增加代码,把功能增加上去就可以。但是我觉得那样对我原理的代码框架影响较大,基于尽量不影响原来的代码的考虑,我想到了decorator 。&&& 先把代码贴出来,在做解释吧:
&&&&public&class&eventstream&:&stream&&&&{&&&&&&&&public&event&eventhandler&fstreamdataeventargs&&&&&&&&&&public&event&eventhandler&fstreamdataeventargs&&&&&&&&&&private&stream&&&&&&&&&public&eventstream(stream&stream)&&&&&&&&{&&&&&&&&&&&&if&(stream&==&null)&throw&new&argumentnullexception("eventstream");&&&&&&&&&&&&this.stream&=&&&&&&&&&}&&&&&&&&[&====&stream&members&====&]#region&[&====&stream&members&====&]&&&&&&&&public&override&bool&canread&&&&&&&&{&&&&&&&&&&&&get&{&return&stream.&}&&&&&&&&}&&&&&&&&public&override&bool&canseek&&&&&&&&{&&&&&&&&&&&&get&{&return&stream.&}&&&&&&&&}&&&&&&&&public&override&bool&canwrite&&&&&&&&{&&&&&&&&&&&&get&{&return&stream.&}&&&&&&&&}&&&&&&&&public&override&void&flush()&&&&&&&&{&&&&&&&&&&&&stream.flush();&&&&&&&&}&&&&&&&&public&override&long&length&&&&&&&&{&&&&&&&&&&&&get&{&return&stream.&}&&&&&&&&}&&&&&&&&public&override&long&position&&&&&&&&{&&&&&&&&&&&&get&&&&&&&&&&&&{&&&&&&&&&&&&&&&&return&stream.&&&&&&&&&&&&}&&&&&&&&&&&&set&&&&&&&&&&&&{&&&&&&&&&&&&&&&&stream.position&=&&&&&&&&&&&&&}&&&&&&&&}&&&&&&&&public&override&int&read(byte[]&buffer,&int&offset,&int&count)&&&&&&&&{&&&&&&&&&&&&int&readsize&=&stream.read(buffer,&offset,&count);&&&&&&&&&&&&if&(onbeforeread&!=&null)&&&&&&&&&&&&&&&&onbeforeread(this,&new&fstreamdataeventargs(buffer,&offset,&readsize));&&&&&&&&&&&&return&&&&&&&&&}&&&&&&&&public&override&long&seek(long&offset,&seekorigin&origin)&&&&&&&&{&&&&&&&&&&&&return&stream.seek(offset,&origin);&&&&&&&&}&&&&&&&&public&override&void&setlength(long&value)&&&&&&&&{&&&&&&&&&&&&stream.setlength(value);&&&&&&&&}&&&&&&&&public&override&void&write(byte[]&buffer,&int&offset,&int&count)&&&&&&&&{&&&&&&&&&&&&if&(onbeforewrite&!=&null)&&&&&&&&&&&&&&&&onbeforewrite(this,&new&fstreamdataeventargs(buffer,&offset,&count));&&&&&&&&&&&&stream.write(buffer,&offset,&count);&&&&&&&&}&&&&&&&&public&override&iasyncresult&beginread(byte[]&buffer,&int&offset,&int&count,&&&&&&&&&&&&&asynccallback&callback,&object&state)&&&&&&&&{&&&&&&&&&&&&internalasyncstate&mystate&=&new&internalasyncstate(&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&new&fstreamdataeventargs(buffer,&offset,&count),&state);&&&&&&&&&&&&asynccallback&mycallback&=&new&asynccallback(&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&new&internalcallback(onbeforeread,&callback).callback);&&&&&&&&&&&&return&new eventstreamasyncresult(&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&stream.beginread(buffer,&offset,&count,&mycallback,&mystate));&&&&&&&&}&&&&&&&&public&override&int&endread(iasyncresult&asyncresult)&&&&&&&&{&&&&&&&&&&&&eventstreamasyncresult&esar&=&asyncresult&as&ev&&&&&&&&&&&&if&(esar&!=&null)&&&&&&&&&&&&&&&&return&stream.endread(esar.internalasyncresult);&&&&&&&&&&&&else&&&&&&&&&&&&&&&&return&stream.endread(asyncresult);&&&&&&&&}&&&&&&&&public&override&iasyncresult&beginwrite(byte[]&buffer,&int&offset,&int&count,&asynccallback&callback,&object&state)&&&&&&&&{&&&&&&&&&&&&internalasyncstate&mystate&=&new&internalasyncstate(&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&new&fstreamdataeventargs(buffer,&offset,&count),&state);&&&&&&&&&&&&asynccallback&mycallback&=&new&asynccallback(&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&new&internalcallback(onbeforewrite,&callback).callback);&&&&&&&&&&&&return&new&eventstreamasyncresult(&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&stream.beginwrite(buffer,&offset,&count,&mycallback,&mystate));&&&&&&&&}&&&&&&&&public&override&void&en ite(iasyncresult&asyncresult)&&&&&&&&{&&&&&&&&&&&&stream.en ite(asyncresult);&&&&&&&&}&&&&&&&&#endregion&&&&&&&&private&class&internalcallback&&&&&&&&{&&&&&&&&&&&&private&asynccallback&&&&&&&&&&&&&private&eventhandler&fstreamdataeventargs&&&&&&&&&&&&&&public&internalcallback(eventhandler&fstreamdataeventargs&&internalhandler,&asynccallback&callback)&&&&&&&&&&&&{&&&&&&&&&&&&&&&&this.internalhandler&=&&&&&&&&&&&&&&&&&this.callback&=&&&&&&&&&&&&&}&&&&&&&&&&&&internal&void&callback(iasyncresult&asyncresult)&&&&&&&&&&&&{&&&&&&&&&&&&&&&&internalasyncstate&mystate&=&asyncresult.asyncstate&as&&&&&&&&&&&&&&&&&if&(internalhandler&!=&null&&&&mystate&!=&null)&&&&&&&&&&&&&&&&&&&&internalhandler(this,&mystate.streamdataeventargs);&&&&&&&&&&&&&&&&callback(new&eventstreamasyncresult(asyncresult));&&&&&&&&&&&&}&&&&&&&&}&&&&&&&&private&class&internalasyncstate&&&&&&&&{&&&&&&&&&&&&object&&&&&&&&&&&&&fstreamdataeventargs&&&&&&&&&&&&&public&object&state&&&&&&&&&&&&{&&&&&&&&&&&&&&&&get&{&return&&}&&&&&&&&&&&&}&&&&&&&&&&&&public&fstreamdataeventargs&streamdataeventargs&&&&&&&&&&&&{&&&&&&&&&&&&&&&&get&{&return&&}&&&&&&&&&&&&}&&&&&&&&&&&&public&internalasyncstate(fstreamdataeventargs&streamdataeventargs,&object&state)&&&&&&&&&&&&{&&&&&&&&&&&&&&&&this.streamdataeventargs&=&&&&&&&&&&&&&&&&&this.state&=&&&&&&&&&&&&&}&&&&&&&&}&&&&&&&&private&class&eventstreamasyncresult&:&iasyncresult&&&&&&&&{&&&&&&&&&&&&iasyncresult&&&&&&&&&&&&&public&eventstreamasyncresult(iasyncresult&ar)&&&&&&&&&&&&{&&&&&&&&&&&&&&&&if&(ar&==&null)&throw&new&argumentnullexception("eventstreamasyncresult");&&&&&&&&&&&&&&&&this.ar&=&&&&&&&&&&&&&}&&&&&&&&&&&&iasyncresult&members#region&iasyncresult&members&&&&&&&&&&&&public&object&asyncstate&&&&&&&&&&&&{&&&&&&&&&&&&&&&&get&&&&&&&&&&&&&&&&{&&&&&&&&&&&&&&&&&&&&internalasyncstate&mystate&=&ar.asyncstate&as&&&&&&&&&&&&&&&&&&&&&if&(mystate&!=&null)&&&&&&&&&&&&&&&&&&&&&&&&return&mystate.&&&&&&&&&&&&&&&&&&&&else&&&&&&&&&&&&&&&&&&&&&&&&return&ar.&&&&&&&&&&&&&&&&}&&&&&&&&&&&&}&&&&&&&&&&&&internal&iasyncresult&internalasyncresult&&&&&&&&&&&&{&&&&&&&&&&&&&&&&get&{&return&&}&&&&&&&&&&&&}&&&&&&&&&&&&public&system.threading.waithandle&asyncwaithandle&&&&&&&&&&&&{&&&&&&&&&&&&&&&&get&{&return&ar.&}&&&&&&&&&&&&}&&&&&&&&&&&&public&bool&completedsynchronously&&&&&&&&&&&&{&&&&&&&&&&&&&&&&get&{&return&&}&&&&&&&&&&&&}&&&&&&&&&&&&public&bool&iscompleted&&&&&&&&&&&&{&&&&&&&&&&&&&&&&get&{&return&ar.&}&&&&&&&&&&&&}&&&&&&&&&&&&#endregion&&&&&&&&}&&&&}&&&&public&class&fstreamdataeventargs&:&eventargs&&&&{&&&&&&&&private&byte[]&&&&&&&&&private&int&&&&&&&&&private&int&&&&&&&&&public&fstreamdataeventargs(byte[]&buffer,&int&offset,&int&count)&&&&&&&&{&&&&&&&&&&&&if(buffer&==&null)&throw&new&argumentnullexception("fstreamdataeventargs");&&&&&&&&&&&&if(offset&+&count&buffer.length)&throw&new&argumentoutofrangeexception("fstreamdataeventargs");&&&&&&&&&&&&this.buffer&=&&&&&&&&&&&&&this.offset&=&&&&&&&&&&&&&this.count&=&&&&&&&&&}&&&&&&&&/**////&&summary&&&&&&&&&///&数据缓存&&&&&&&&///&&/summary&&&&&&&&&public&byte[]&buffer&&&&&&&&{&&&&&&&&&&get&{&return&&}&&&&&&&&}&&&&&&&&/**////&&summary&&&&&&&&&///&数据开始位置&&&&&&&&///&&/summary&&&&&&&&&public&int&offset&&&&&&&&{&&&&&&&&&&get&{&return&&}&&&&&&&&}&&&&&&&&/**////&&summary&&&&&&&&&///&数据长度&&&&&&&&///&&/summary&&&&&&&&&public&int&count&&&&&&&&{&&&&&&&&&&get&{&return&&}&&&&&&&&}&&&&}
刚开始以为很简单,事实上写下来还挺多行代码的,^_^。decorator模式嘛,当然先继承stream,把stream本来该做的事情先完成了。这个很简单类里面包含一个内部的stream,stream该有的接口都由它来完成了。接下来就是增加两个事件,分别是onbeforeread、onbeforewrite。名字里面都有before,其实我考虑到数据流都会通过这两个事件开放出来,你想做加密什么的都可以,当然也包括我想要的统计数据流量。接下来就是在读写流的时候触发这两个事件就可以了。看看同步的read、write方法,简单的调用就可以了。关键的地方就在于异步的读写。我们先看看一般stream的异步调用代码是怎么样的:
stream.beginread(buffer,&<span style="color: #,&byte2read,&new&asynccallback(endreadcallback), state);private&void&endreadcallback(iasyncresult&asyncresult){&&&&object&state&=&asyncresult.&&&&nreadsize&=&stream.endread(asyncresult);&&&&&&&&&&&&//}
在不更改这个&#8220;client&#8221;代码的情况下,要怎么样在stream那边知道这里的确实读了多少数据呢?&显然在调用beginread的时候是不知道,那就只能对这个asynccallback做手脚了。可以预想到framework内部会在完成了read的操作之后会调用asynccallback委托来通知结果。于是我就传一个我定义好的asynccallback委托给beginread。当然还要把&#8220;client&#8221;提供的asynccallback给包装起来,在做完我的事情(事件通知)之后,还是要把&#8220;client&#8221;要我办的事情给也给办了(调用"client"的asynccallback委托来通知结果)。这就在实现了&#8220;在客户代码与framework之间插一脚&#8221;。再来看看我是怎么做到事件通知的。首先要把我要的数据此文来自: 马开东博客
转载请注明出处 网址:
给传过去,于是有了internalasyncstate,这里面要有我触发事件需要的事件参数,还应该要包括用户可能传入的state。具体大家看看internalasyncstate的实现。最后多考虑了一点就是,假如&#8220;client&#8221;代码不是像我写的那样,而是不断的通过检查stream.beginread 方法返回的iasyncresult的iscompleted属性来确定是否read完成的话,那我的代码就有问题了,我返回的iasyncresult根本就不是原理的iasyncresult了。eventstreamasyncresult类就是为这个而写的。下面是使用的代码:
public&void&getresponsestream(){&&&&&&&&eventstream&es&=&new&eventstream(tcpclient.netstream);&&&&&&&&es.onbeforeread&+=&new&eventhandler&fstreamdataeventargs&(eventstream_onbeforeread);&&&&&&&&es.onbeforewrite&+=&new&eventhandler&fstreamdataeventargs&(eventstream_onbeforewrite);&&&&&&&&return&}
回头看看代码,其实都在用decorator模式的思想,把原来的framework中的类都给包装起来,并在完成原来的功能之余另外加了自己的功能.。文笔一般,希望能对你有帮助。
搜索此文相关文章:此文来自: 马开东博客
网址: 站长QQ
实战Decorator模式:封装stream,在读写stream时提供事件通知_博客园相关文章
博客园_总排行榜
博客园_最新
博客园_月排行榜
博客园_周排行榜
博客园_日排行榜安全检查中...
请打开浏览器的javascript,然后刷新浏览器
< 浏览器安全检查中...
还剩 5 秒&所有回答(3)
这种情况产生的原因是,如果读取一端比发送端的读取速度要快,这时候接收端的数据已读完并已经清空了,所以接收端认为这一次通信已完成,但是发送端还在继续发送就产生了读不全的问题,.net的底层存在这种情况,数据读取最好用while循环去读取,不要一次性读取多少个字节,一次性读取多少个字节在某些网络环境不佳的情况下就出现你那种问题了。
while(streamServer.DataAvailable)
看看,我使用这种读法是可以的。
园豆:8243
肯定收不全,TcpClient& NetworkStream& 是基于流的 ,DataAvailable只能标识缓冲是否有数据可读,DataAvailable在TCP中并不是充当信息边界的,楼主要纠正一下自己的思路。
如果读取HTTP,比较简单的方式是使用WEBCLIENT助手类。
如果一定要用TCP,那么需要先行获取文件标头中的文件尺寸后再读取或是按照协议读取,而不是这样没头没闹的读取。
你ReadTimeout 的方法是谁教的!体育老师?太 可怕了,绝不是这样用的
服务器端数据发完了,但是客户端收不到结束信号,好好查了一下原因,问题出在ie自动产生的http包头Connection域默认为keep-alive,代理这边收到包后更改为close后就能及时收到服务器端数据发完后给出的结束信号了,这问题解决后就可以很流畅的运行了
&&&您需要以后才能回答,未注册用户请先。posts - 64,&
comments - 192,&
trackbacks - 0
1.添加命名空间
  System.IO;
  System.T
2.文件的读取
  (1).使用FileStream类进行文件的读取,并将它转换成char数组,然后输出。
byte[] byData = new byte[100];
char[] charData = new char[1000];
public void Read()
FileStream file = new FileStream("E:\\test.txt", FileMode.Open);
file.Seek(0, SeekOrigin.Begin);
file.Read(byData, 0, 100); //byData传进来的字节数组,用以接受FileStream对象中的数据,第2个参数是字节数组中开始写入数据的位置,它通常是0,表示从数组的开端文件中向数组写数据,最后一个参数规定从文件读多少字符.
Decoder d = Encoding.Default.GetDecoder();
d.GetChars(byData, 0, byData.Length, charData, 0);
Console.WriteLine(charData);
file.Close();
catch (IOException e)
Console.WriteLine(e.ToString());
  (2).使用StreamReader读取文件,然后一行一行的输出。
public void Read(string path)
StreamReader sr = new StreamReader(path,Encoding.Default);
while ((line = sr.ReadLine()) != null)
Console.WriteLine(line.ToString());
3.文件的写入  (1).使用FileStream类创建文件,然后将数据写入到文件里。
public void Write()
FileStream fs = new FileStream("E:\\ak.txt", FileMode.Create);
//获得字节数组
byte[] data = System.Text.Encoding.Default.GetBytes("Hello World!");
//开始写入
fs.Write(data, 0, data.Length);
//清空缓冲区、关闭流
fs.Flush();
fs.Close();
  (2).使用FileStream类创建文件,使用StreamWriter类,将数据写入到文件。
public void Write(string path)
FileStream fs = new FileStream(path, FileMode.Create);
StreamWriter sw = new StreamWriter(fs);
//开始写入
sw.Write("Hello World!!!!");
//清空缓冲区
sw.Flush();
sw.Close();
fs.Close();
  以上就完成了,txt文本文档的数据读取与写入。
阅读(...) 评论()

我要回帖

更多关于 iic读写时序 的文章

 

随机推荐