First, Introduction
Bufferedinputstream caches a subset of the data (the default 8K), which is the function of reading more data into the cache and expanding the cached content when necessary.
There are several important flag bits in this class: Markpos,pos,count
"Therole of Markpos, the data in the Marklength region represents the data that needs to be retained, that is, when the reset method is in buffer, this part of the data is not deleted, forcing retention . 】
Pos:
Current position in the buffer, which is the index of the next character to be read from the buffer.
Represents the next character that will be read in.
Markpos:
The value of the POS field at the time the last mark method is called.
The value of Markpos equals the POS position when the mark method was last called.
1 Public synchronized void mark (int readlimit) {2 marklimit = readlimit; 3 markpos = pos; 4 }
Count
The buffer that can be used
Two, fill () function
When Pos>count, call this method to enlarge. It always moves the location of the reserved space to the front of the buffer.
1 Private voidFill ()throwsIOException {2 byte[] buffer =Getbufifopen ();3 if(Markpos < 0)4pos = 0;/*no mark:throw away the buffer*/5 Else if(POS >= buffer.length)/*No in Buffer*/6 if(Markpos > 0) {/*can throw away early part of the buffer*/7 intSZ = pos-Markpos;8System.arraycopy (buffer, markpos, buffer, 0, SZ);9pos =sz;TenMarkpos = 0; One}Else if(Buffer.length >=marklimit) { AMarkpos =-1;/*buffer got too big, invalidate Mark*/ -pos = 0;/*Drop Buffer Contents*/ -}Else{/*Grow Buffer*/ the intNsz = pos * 2; - if(Nsz >marklimit) -Nsz =Marklimit; - byteNbuf[] =New byte[Nsz]; +System.arraycopy (buffer, 0, nbuf, 0, POS); - if(!bufupdater.compareandset ( This, buffer, nbuf)) { + //Can ' t replace BUF if there is an async close. A //Note:this would need to be changed if fill () at //Is ever made accessible to multiple threads. - //the only-to-do CAS can fail is via close. - //assert buf = = null; - Throw NewIOException ("Stream closed"); - } -Buffer =Nbuf; in } -Count =Pos; to intn = Getinifopen (). Read (buffer, POS, buffer.length-POS); + if(N > 0) -Count = n +Pos; the}
byte[] buffer = Getbufifopen (); Get a reference to the current buffer
if (Markpos < 0)
pos = 0; /* No mark:throw away the buffer */ the entire buffer is not marked, that is, there is no space reserved .
else if (POS >= buffer.length)/* No room is left in buffer */(markpos >0 or = 0) has reserved space and no remaining space is available.
if (Markpos > 0) {/* can throw away early part of the buffer * * The starting position of the reserved space is not at the beginning of the buffer
int sz = Pos-markpos; Move aside Space
System.arraycopy (buffer, markpos, buffer, 0, SZ);
pos = SZ;
Markpos = 0;
} else if (buffer.length >= marklimit) { If the value of Marklimit is less than the length of the cache, the buffer is large, from the point of view of memory usage, it is not appropriate to increase the capacity of the cache at this time,
In this case, discard the existing contents of BUF directly;
Markpos =-1; /* Buffer got too big, invalidate mark */
pos = 0; /* Drop Buffer contents */
} else {/* Grow buffer */twice x Extended buffer
int NSZ = pos * 2;
if (Nsz > Marklimit)
Nsz = Marklimit;
byte nbuf[] = new Byte[nsz];
System.arraycopy (buffer, 0, nbuf, 0, POS);
if (!bufupdater.compareandset (this, buffer, nbuf)) {ensure visibility in multithreaded situations.
Can ' t replace BUF if there is an async close.
//Note:this would need to be changed if fill ()
//Is ever made accessible to multiple threads.
The only-to-do CAS can fail is via close.
assert buf = = null;
throw new IOException ("Stream closed");
}
buffer = Nbuf;
}
Bufferedinputstream Source Code Analysis