从PipedInputStreamPipedOutputStream谈起.docx
- 文档编号:30744484
- 上传时间:2023-08-20
- 格式:DOCX
- 页数:18
- 大小:67.43KB
从PipedInputStreamPipedOutputStream谈起.docx
《从PipedInputStreamPipedOutputStream谈起.docx》由会员分享,可在线阅读,更多相关《从PipedInputStreamPipedOutputStream谈起.docx(18页珍藏版)》请在冰豆网上搜索。
从PipedInputStreamPipedOutputStream谈起
从PipedInputStream/PipedOutputStream谈起
1 源代码分析
下面将详细分析PipedInputStream和PipedOutputStream的源代码。
1.1PipedInputStream
packagejava.io;
//PipedInputStream必须和PipedOutputStream联合使用。
即必须连接输入部分。
//其原理为:
PipedInputStream内部有一个Buffer,
//PipedInputStream可以使用InputStream的方法读取其Buffer中的字节。
//PipedInputStream中Buffer中的字节是PipedOutputStream调用PipedInputStream的方法放入的。
publicclassPipedInputStreamextendsInputStream{
booleanclosedByWriter=false; //标识有读取方或写入方关闭
volatilebooleanclosedByReader=false;
booleanconnected=false; //是否建立连接
ThreadreadSide; //标识哪个线程
ThreadwriteSide;
protectedstaticfinalintPIPE_SIZE=1024; //缓冲区的默认大小
protectedbytebuffer[]=newbyte[PIPE_SIZE]; //缓冲区
protectedintin=-1; //下一个写入字节的位置。
0代表空,in==out代表满
protectedintout=0; //下一个读取字节的位置
publicPipedInputStream(PipedOutputStreamsrc)throwsIOException{ //给定源的输入流
connect(src);
}
publicPipedInputStream(){ } //默认构造器,下部一定要connect源
publicvoidconnect(PipedOutputStreamsrc)throwsIOException{ //连接输入源
src.connect(this); //调用源的connect方法连接当前对象
}
protectedsynchronizedvoidreceive(intb)throwsIOException{ //只被PipedOuputStream调用
checkStateForReceive(); //检查状态,写入
writeSide=Thread.currentThread(); //永远是PipedOuputStream
if(in==out) awaitSpace(); //输入和输出相等,等待空间
if(in<0){
in=0;
out=0;
}
buffer[in++]=(byte)(b&0xFF); //放入buffer相应的位置
if(in>=buffer.length){ in=0; } //in为0表示buffer已空
}
synchronizedvoidreceive(byteb[],intoff,intlen) throwsIOException{
checkStateForReceive();
writeSide=Thread.currentThread(); //从PipedOutputStream可以看出
intbytesToTransfer=len;
while(bytesToTransfer>0){
if(in==out) awaitSpace(); //满了,会通知读取的;空会通知写入
intnextTransferAmount=0;
if(out nextTransferAmount=buffer.length-in; }elseif(in if(in==-1){ in=out=0; nextTransferAmount=buffer.length-in; }else{ nextTransferAmount=out-in; } } if(nextTransferAmount>bytesToTransfer) nextTransferAmount=bytesToTransfer; assert(nextTransferAmount>0); System.arraycopy(b,off,buffer,in,nextTransferAmount); bytesToTransfer-=nextTransferAmount; off+=nextTransferAmount; in+=nextTransferAmount; if(in>=buffer.length){ in=0; } } } privatevoidcheckStateForReceive()throwsIOException{ //检查当前状态,等待输入 if(! connected){ thrownewIOException("Pipenotconnected"); }elseif(closedByWriter||closedByReader){ thrownewIOException("Pipeclosed"); }elseif(readSide! =null&&! readSide.isAlive()){ thrownewIOException("Readenddead"); } } privatevoidawaitSpace()throwsIOException{ //Buffer已满,等待一段时间 while(in==out){ //in==out表示满了,没有空间 checkStateForReceive(); //检查接受端的状态 notifyAll(); //通知读取端 try{ wait(1000); }catch(InterruptedExceptionex){ thrownewjava.io.InterruptedIOException(); } } } synchronizedvoidreceivedLast(){ //通知所有等待的线程()已经接受到最后的字节 closedByWriter=true; // notifyAll(); } publicsynchronizedintread() throwsIOException{ if(! connected){ //检查一些内部状态 thrownewIOException("Pipenotconnected"); }elseif(closedByReader){ thrownewIOException("Pipeclosed"); }elseif(writeSide! =null&&! writeSide.isAlive()&&! closedByWriter&&(in<0)){ thrownewIOException("Writeenddead"); } readSide=Thread.currentThread(); //当前线程读取 inttrials=2; //重复两次? ? ? ? while(in<0){ if(closedByWriter){ return-1; } //输入断关闭返回-1 if((writeSide! =null)&&(! writeSide.isAlive())&&(--trials<0)){ //状态错误 thrownewIOException("Pipebroken"); } notifyAll(); // 空了,通知写入端可以写入 try{ wait(1000); }catch(InterruptedExceptionex){ thrownewjava.io.InterruptedIOException(); } } intret=buffer[out++]&0xFF; // if(out>=buffer.length){ out=0; } if(in==out){ in=-1; } //没有任何字节 returnret; } publicsynchronizedintread(byteb[],intoff,intlen) throwsIOException{ if(b==null){ //检查输入参数的正确性 thrownewNullPointerException(); }elseif(off<0||len<0||len>b.length-off){ thrownewIndexOutOfBoundsException(); }elseif(len==0){ return0; } intc=read(); //读取下一个 if(c<0){ return-1; } //已经到达末尾了,返回-1 b[off]=(byte)c; //放入外部buffer中 intrlen=1; //return-len while((in>=0)&&(--len>0)){ //下一个in存在,且没有到达len b[off+rlen]=buffer[out++]; //依次放入外部buffer rlen++; if(out>=buffer.length){ out=0; } //读到buffer的末尾,返回头部 if(in==out){ in=-1; } //读、写位置一致时,表示没有数据 } returnrlen; //返回填充的长度 } publicsynchronizedintavailable()throwsIOException{ //返回还有多少字节可以读取 if(in<0) return0; //到达末端,没有字节 elseif(in==out) returnbuffer.length; //写入的和读出的一致,表示满 elseif(in>out) returnin-out; //写入的大于读出 else returnin+buffer.length-out; //写入的小于读出的 } publicvoidclose() throwsIOException{ //关闭当前流,同时释放与其相关的资源 closedByReader=true; //表示由输入流关闭 synchronized(this){ in=-1; } //同步化当前对象,in为-1 } } 1.2PipedOutputStream //PipedOutputStream一般必须和一个PipedInputStream连接。 共同构成一个pipe。 //它们的职能是: packagejava.io; importjava.io.*; publicclassPipedOutputStreamextendsOutputStream{ privatePipedInputStreamsink; //包含一个PipedInputStream publicPipedOutputStream(PipedInputStreamsnk)throwsIOException{ //带有目的地的构造器 connect(snk); } publicPipedOutputStream(){ } //默认构造器,必须使用下面的connect方法连接 publicsynchronizedvoidconnect(PipedInputStreamsnk)throwsIOException{ if(snk==null){ //检查输入参数的正确性 thrownewNullPointerException(); }elseif(sink! =null||snk.connected){ thrownewIOException("Alreadyconnected"); } sink=snk; //一系列初始化工作 snk.in=-1; snk.out=0; snk.connected=true; } publicvoidwrite(intb)throwsIOException{ //向流中写入数据 if(sink=
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- PipedInputStreamPipedOutputStream 谈起
![提示](https://static.bdocx.com/images/bang_tan.gif)