|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
在ruby里才是一切皆对象。当然我不并不是很了解ruby,但是ruby确实是将语法简化得很好。
BufferedInputStream(缓冲输出流)的认知、源码和示例
本章内容包含3个部分:BufferedInputStream先容,BufferedInputStream源码,和BufferedInputStream利用示例。
BufferedInputStream先容
BufferedInputStream是缓冲输出流。它承继于FilterInputStream。
BufferedInputStream的感化是为另外一个输出流增加一些功效,比方,供应“缓冲功效”和撑持“mark()标志”和“reset()重置办法”。
BufferedInputStream实质上是经由过程一个外部缓冲区数组完成的。比方,在新建某输出流对应的BufferedInputStream后,当我们经由过程read()读取输出流的数据时,BufferedInputStream会将该输出流的数据分批的填进到缓冲区中。每当缓冲区中的数据被读完以后,输出流会再次添补数据缓冲区;云云重复,直到我们读完输出流数据地位。
BufferedInputStream函数列表- BufferedInputStream(InputStreamin)
- BufferedInputStream(InputStreamin,intsize)
- synchronizedintavailable()
- voidclose()
- synchronizedvoidmark(intreadlimit)
- booleanmarkSupported()
- synchronizedintread()
- synchronizedintread(byte[]buffer,intoffset,intbyteCount)
- synchronizedvoidreset()
- synchronizedlongskip(longbyteCount)
复制代码 BufferedInputStream源码剖析(基于jdk1.7.40)- packagejava.io;
- importjava.util.concurrent.atomic.AtomicReferenceFieldUpdater;
- publicclassBufferedInputStreamextendsFilterInputStream{
- //默许的缓冲巨细是8192字节
- //BufferedInputStream会依据“缓冲区巨细”来逐次的添补缓冲区;
- //即,BufferedInputStream添补缓冲区,用户读取缓冲区,读完以后,BufferedInputStream会再次添补缓冲区。云云轮回,直到读完数据...
- privatestaticintdefaultBufferSize=8192;
- //缓冲数组
- protectedvolatilebytebuf[];
- //缓存数组的原子更新器。
- //该成员变量与buf数组的volatile关头字配合构成了buf数组的原子更新功效完成,
- //即,在多线程中操纵BufferedInputStream对象时,buf和bufUpdater都具有原子性(分歧的线程会见到的数据都是不异的)
- privatestaticfinal
- AtomicReferenceFieldUpdater<BufferedInputStream,byte[]>bufUpdater=
- AtomicReferenceFieldUpdater.newUpdater
- (BufferedInputStream.class,byte[].class,"buf");
- //以后缓冲区的无效字节数。
- //注重,这里是指缓冲区的无效字节数,而不是输出流中的无效字节数。
- protectedintcount;
- //以后缓冲区的地位索引
- //注重,这里是指缓冲区的地位索引,而不是输出流中的地位索引。
- protectedintpos;
- //以后缓冲区的标志地位
- //markpos和reset()共同利用才成心义。操纵步骤:
- //(01)经由过程mark()函数,保留pos的值到markpos中。
- //(02)经由过程reset()函数,会将pos的值重置为markpos。接着经由过程read()读取数据时,就会从mark()保留的地位入手下手读取。
- protectedintmarkpos=-1;
- //marklimit是标志的最年夜值。
- //检察本栏目更多出色内容:http://www.bianceng.cn/Programming/Java/
- //关于marklimit的道理,我们在前面的fill()函数剖析中会具体申明。这对了解BufferedInputStream相称主要。
- protectedintmarklimit;
- //猎取输出流
- privateInputStreamgetInIfOpen()throwsIOException{
- InputStreaminput=in;
- if(input==null)
- thrownewIOException("Streamclosed");
- returninput;
- }
- //猎取缓冲
- privatebyte[]getBufIfOpen()throwsIOException{
- byte[]buffer=buf;
- if(buffer==null)
- thrownewIOException("Streamclosed");
- returnbuffer;
- }
- //机关函数:新建一个缓冲区巨细为8192的BufferedInputStream
- publicBufferedInputStream(InputStreamin){
- this(in,defaultBufferSize);
- }
- //机关函数:新建指定缓冲区巨细的BufferedInputStream
- publicBufferedInputStream(InputStreamin,intsize){
- super(in);
- if(size<=0){
- thrownewIllegalArgumentException("Buffersize<=0");
- }
- buf=newbyte[size];
- }
- //从“输出流”中读取数据,并添补到缓冲区中。
- //前面会对该函数举行具体申明!
- privatevoidfill()throwsIOException{
- byte[]buffer=getBufIfOpen();
- if(markpos<0)
- pos=0;/*nomark:throwawaythebuffer*/
- elseif(pos>=buffer.length)/*noroomleftinbuffer*/
- if(markpos>0){/*canthrowawayearlypartofthebuffer*/
- intsz=pos-markpos;
- System.arraycopy(buffer,markpos,buffer,0,sz);
- pos=sz;
- markpos=0;
- }elseif(buffer.length>=marklimit){
- markpos=-1;/*buffergottoobig,invalidatemark*/
- pos=0;/*dropbuffercontents*/
- }else{/*growbuffer*/
- intnsz=pos*2;
- if(nsz>marklimit)
- nsz=marklimit;
- bytenbuf[]=newbyte[nsz];
- System.arraycopy(buffer,0,nbuf,0,pos);
- if(!bufUpdater.compareAndSet(this,buffer,nbuf)){
- thrownewIOException("Streamclosed");
- }
- buffer=nbuf;
- }
- count=pos;
- intn=getInIfOpen().read(buffer,pos,buffer.length-pos);
- if(n>0)
- count=n+pos;
- }
- //读取下一个字节
- publicsynchronizedintread()throwsIOException{
- //若已读完缓冲区中的数据,则挪用fill()从输出流读取下一部分数据来添补缓冲区
- if(pos>=count){
- fill();
- if(pos>=count)
- return-1;
- }
- //从缓冲区中读取指定的字节
- returngetBufIfOpen()[pos++]&0xff;
- }
- //将缓冲区中的数据写进到字节数组b中。off是字节数组b的肇端地位,len是写进长度
- privateintread1(byte[]b,intoff,intlen)throwsIOException{
- intavail=count-pos;
- if(avail<=0){
- //减速机制。
- //假如读取的长度年夜于缓冲区的长度而且没有markpos,
- //则间接从原始输出流中举行读取,从而制止无谓的COPY(从原始输出流至缓冲区,读取缓冲区全体数据,清空缓冲区,
- //从头填进原始输出流数据)
- if(len>=getBufIfOpen().length&&markpos<0){
- returngetInIfOpen().read(b,off,len);
- }
- //若已读完缓冲区中的数据,则挪用fill()从输出流读取下一部分数据来添补缓冲区
- fill();
- avail=count-pos;
- if(avail<=0)return-1;
- }
- intcnt=(avail<len)?avail:len;
- System.arraycopy(getBufIfOpen(),pos,b,off,cnt);
- pos+=cnt;
- returncnt;
- }
- //将缓冲区中的数据写进到字节数组b中。off是字节数组b的肇端地位,len是写进长度
- publicsynchronizedintread(byteb[],intoff,intlen)
- throwsIOException
- {
- getBufIfOpen();//Checkforclosedstream
- if((off|len|(off+len)|(b.length-(off+len)))<0){
- thrownewIndexOutOfBoundsException();
- }elseif(len==0){
- return0;
- }
- //读取到指定长度的数据才前往
- intn=0;
- for(;;){
- intnread=read1(b,off+n,len-n);
- if(nread<=0)
- return(n==0)?nread:n;
- n+=nread;
- if(n>=len)
- returnn;
- //ifnotclosedbutnobytesavailable,return
- InputStreaminput=in;
- if(input!=null&&input.available()<=0)
- returnn;
- }
- }
- //疏忽n个字节
- publicsynchronizedlongskip(longn)throwsIOException{
- getBufIfOpen();//Checkforclosedstream
- if(n<=0){
- return0;
- }
- longavail=count-pos;
- if(avail<=0){
- //Ifnomarkpositionsetthendontkeepinbuffer
- if(markpos<0)
- returngetInIfOpen().skip(n);
- //Fillinbuffertosavebytesforreset
- fill();
- avail=count-pos;
- if(avail<=0)
- return0;
- }
- longskipped=(avail<n)?avail:n;
- pos+=skipped;
- returnskipped;
- }
- //下一个字节是不是存可读
- publicsynchronizedintavailable()throwsIOException{
- intn=count-pos;
- intavail=getInIfOpen().available();
- returnn>(Integer.MAX_VALUE-avail)
- ?Integer.MAX_VALUE
- :n+avail;
- }
- //标志“缓冲区”中以后地位。
- //readlimit是marklimit,关于marklimit的感化,参考前面的申明。
- publicsynchronizedvoidmark(intreadlimit){
- marklimit=readlimit;
- markpos=pos;
- }
- //将“缓冲区”中以后地位重置到mark()所标志的地位
- publicsynchronizedvoidreset()throwsIOException{
- getBufIfOpen();//Causeexceptionifclosed
- if(markpos<0)
- thrownewIOException("Resettingtoinvalidmark");
- pos=markpos;
- }
- publicbooleanmarkSupported(){
- returntrue;
- }
- //封闭输出流
- publicvoidclose()throwsIOException{
- byte[]buffer;
- while((buffer=buf)!=null){
- if(bufUpdater.compareAndSet(this,buffer,null)){
- InputStreaminput=in;
- in=null;
- if(input!=null)
- input.close();
- return;
- }
- //ElseretryincaseanewbufwasCASedinfill()
- }
- }
- }
复制代码 <p>
C#是盗用了Java的源代码,仿照开发的,原因是Java是开源的啊,盗了也白盗,还有一点,开发C#语言的团队是就是开发Java语言的团队,是微软重金挖过去的啊 |
|