JDK source code reading (1) _ introduction + java. io, jdkjava. io
1. Introduction
For this forum, I will take a Java 8 source code reading note. Some java packages that are widely used in java Web are intensively read with comments attached. Compare and analyze confusing knowledge points.
The source code sequence of Intensive Reading is as follows:
(1) Part 1: This part is the most common java development package and class, which requires intensive reading:
- Java. io
- Java. lang
- Java. util
(2) Part 2: This part is one of the core content of java web development and requires a deep understanding. (Including java reflection, network I/O, non-blocking, and concurrent programming) ---- some experts say that this part of the application is good or bad, and the level of mastery is high, will determine the level of a java developer:
- Java. lang. reflect
- Java.net
- Javax.net .*
- Java. nio
- Java. util. concurrent .*
(3) Part 3: This part does not have high requirements. You can simply perform extensive reading, understand, and use it:
- Java, lang. annotation
- Javax. annotation
- Java. lang. ref
- Java. math
- Java. rmi .*
- Javax. rmi .*
- Java. security .*
- Javax. security .*
- Java. SQL
- Javax. SQL .*
- Javax. transaction .*
- Java. test
- Java. xml .*
- Org. w3c. dom .*
- Org. xml. sax .*
- Javax. crypto .*
- Javax. imageio .*
- Javax. jws .*
- Java. util. jar
- Java. util. logging
- Java. util. prefs
- Java. util. regex
- Java.util.zip
2. Read the source code: -- day1 :( java. io _BufferedInputStream class)
(1) java. io -- BufferedInputStream class
Package java. io;
// The java. io package provides system input and output import java. util. concurrent. atomic. AtomicReferenceFieldUpdater through data stream, serialization, and file systems;
// Import a package that uses a multithreaded atomic Updater public class BufferedInputStream extends FilterInputStream {
// Inherit from fileinputstream and add some functions to the input stream. Use it to prevent actual write operations from being performed each time the stream is read, which indicates "using the Buffer Zone"
Private static int DEFAULT_BUFFER_SIZE = 8192;
// This variable defines the default buffer size of 8192;
Private static int MAX_BUFFER_SIZE = Integer. MAX_VALUE-8;
// The maximum length is still Integer. MAX_VALUE, not Integer. MAX_VALUE-8 protected volatile byte buf [];
// An internal buffer array for storing data. If necessary, you can replace it with an array of different sizes;
// Note that the volatile keyword indicates an unstable variable. Each thread access should be read directly from the main program.
// (Acting on a multi-threaded environment) prevents the main program value from changing, and the value of a thread cannot match the corresponding value, causing an error;
Private static final response <BufferedInputStream, byte []> bufUpdater = AtomicReferenceFieldUpdater. newUpdater (BufferedInputStream. class, byte []. class, "buf ");
// Cache an atomic Updater of an array. This member variable is used with the volatile keyword of the buf array to update the atoms of the buf array;
Protected int count;
// The index is 1 larger than the index of the last valid byte in the buffer zone. This value is always in0
Tobuf.length
Within the scope;
// Slavebuf[0]
Tobuf[count-1]
Contains the buffer input data obtained from the underlying input stream.
Protected int pos; // pos = position, the current position in the buffer, which is the index of the next character to be read from the buf array;
// This value is always in0
Tocount
. If this value is lesscount
, Thenbuf[pos]
Will be used as the next input byte;
// If this value is equalcount
, The next timeread
Orskip
The operation needs to read more bytes from the included input stream.
Protected int markpos =-1;
// The Last callmark
Method timepos
The value of the field is-1; the value of markpos is always in-1
Topos
Within the scope,
// This field is-1. If the input stream has a marked positionbuf[markpos]
Usedreset
// The first input byte after the operation. Ifmarkpos
No-1
, The slave locationbuf[markpos]
Tobuf[pos-1]
Between
//All bytes
Must be kept in the buffer Array
(Althoughcount
,pos
Andmarkpos
These bytes may be moved
//Other locations in the buffer array );
Unlesspos
Andmarkpos
The difference exceedsmarklimit
Otherwise, it cannot be discarded.
Protected int marklimit; // callmark
After the method is calledreset
The maximum amount of read ahead allowed before the method fails.
// As longpos
Andmarkpos
The difference exceedsmarklimit
, You canmarkpos
Set-1
To delete the tag. Private InputStream getInIfOpen () throws IOException {InputStream input = in; if (input = null) throw new IOException ("Stream closed"); return input ;}
// If the input stream is null, an exception occurs when the stream is closed.
// If the input stream is not null, the input stream is returned and the data is stored in the input
Private byte [] getbucket open () throws IOException {byte [] buffer = buf; if (buffer = null) throw new IOException ("Stream closed"); return buffer ;} // create an input stream array to save its parameters. When the input parameter array is null, a "stream closed" exception is thrown,
// If it is not null, the array buffer is directly returned and the input stream is stored in the array;
Public BufferedInputStream (InputStream in) {this (in, DEFAULT_BUFFER_SIZE); // in java, use this to reference the current object;} // create a buffer input stream BufferedInputStream and save its data, input stream in for future use;
// Call back to buffer the input stream and save its default parameters (buffer the length of the input stream );
Public BufferedInputStream (InputStream in, int size) {super (in); // use super to reference the parent class in the java class. InputStream is the parent class of BufferedInputSream; if (size <= 0) {throw new IllegalArgumentException ("Buffer size <= 0"); buf = new byte [size];}
// Create a buffer with the specified sizeBufferedInputStream
And save its parameters, that is, the input streamin
,
// For future use. Create a lengthsize
And store it inbuf
.
Private void fill () throws IOException {byte [] buffer = getbucket open (); if (markpos <0) pos = 0; // no mark, always pointing to the initial position of the buffer stream; else if (pos> = buffer. length) // The position is longer than the buffer length, and there is no space in the buffer; if (markpos> 0) {// throw the first half of the buffer; int sz = pos-markpos; // The length of the string data; System. arraycopy (buffer, markpos, buffer, 0, sz); pos = sz; markpos = 0; // copy and initialize pos and markpos;} else if (buffer. length> = marklimit) {markpos =-1; // The buffer area is too large. It is an invalid flag and returns-1; pos = 0; // reduces the buffer content;} else if (buffer. length >=max_buffer_size) {throw new OutOfMemoryError ("Required array size too large");} else {// extended int nsz = (pos <= MAX_BUFFER_SIZE-pos )? Pos * 2: MAX_BUFFER_SIZE; if (nsz> marklimit) nsz = marklimit; byte nbuf [] = new byte [nsz]; System. arraycopy (buffer, 0, nbuf, 0, pos); if (! BufUpdater. compareAndSet (this, buffer, nbuf) {// if it is not synchronized, it cannot be replaced; // note: if it is full, extended transformation is required. // For multithreading, it cannot be achieved. // The only way is to end the process by disabling it. // insert buf = null; throw new IOException ("Stream closed");} buffer = nbuf;} count = pos; int n = getInIfOpen (). read (buffer, pos, buffer. length-pos); if (n> 0) count = n + pos; // quantity}
Public synchronized int read () throws IOException {if (pos> = count) {fill (); // call fill () if the position value pos is greater than or equal to the length count () method if (pos> = count) return-1;} return getbucket open () [pos ++] & 0xff ;}
// Read the string into the array. If needed, the string can be read once at most. private int read1 (byte [] B, int off, int len) throws IOException {int avail = count-pos; if (avail <= 0 ){
// If the request length is at least the same as that of the buffer, and no mark/reset operation is performed;
// Do not rush to copy data. Do not rush to copy bytes to the local buffer. if so, the buffer stream will have harmless cascade; if (len> = getbuw.open (). length & markpos <0) {return getInIfOpen (). read (B, off, len);} fill (); avail = count-pos; if (avail <= 0) return-1 ;} int cnt = (avail <len )? Avail: len; System. arraycopy (getbuw.open (), pos, B, off, cnt); pos ++ = cnt; return cnt ;}
// Read from the input byte stream to the specific byte stream array starting with the given offset; public synchronized int read (byte B [], int off, int len) throws IOException {getbucket open (); // check whether the buffer stream is closed; if (off | len | (off + len) | (B. length-(off + len) <0) {throw new IndexOutOfBoundsException ();} else if (len = 0) {return 0;} int n = 0; for (;) {int nread = read1 (B, off + n, len-n); // read if (nread <= 0) return (n = 0 )? Nread: n; // a simple selection statement. if n = 0, nread is returned; otherwise, n; n + = nread; if (n> = len) return n; // if the input stream is not closed, but no Bytes are available, the system returns directly; InputStream input = in; if (input! = Null & input. available () <= 0) return n ;}}
Public synchronized long skip (long n) throws IOException {// n indicates the number of skip bytes; getbucket open (); // check whether the ignore stream is disabled if (n <= 0) {return 0;} long avail = count-pos; // determine the available length if (avail <= 0) {// if no flag position is set, it is not stored in the buffer; if (markpos <0) return getInIfOpen (). skip (n); // fill the buffer to save the byte and wait for resetting; fill (); avail = count-pos; if (avail <= 0) return 0 ;} long skipped = (avail <n )? Avail: n; // select a judgment statement to skip the avail length or n length. pos + = skipped; return skipped ;}
// Return the estimate of the number of bytes that can be read (or skipped) from the input stream, without blocking the next call to the method of the input stream.
// The next call may be the same thread or another thread. This multi-byte single read or skip does not block, but may read or skip fewer bytes. Public synchronized int available () throws IOException {int n = count-pos; int avail = getInIfOpen (). available (); return n> (Integer. MAX_VALUE-avail )? Integer. MAX_VALUE: n + avail ;}
Public synchronized void mark (int readlimit) {marklimit = readlimit; markpos = pos ;}
// Reset () reset method; public synchronized void reset () throws IOException {getbucket open (); // if the buffer stream is closed, an exception is thrown; if (markpos <0) // if the flag position is smaller than 0, an exception is thrown. throw new IOException ("Resetting to invalid mark"); pos = markpos ;}
Public boolean markSupported () {return true; // test the supported position flag of the input stream ;}
// Close the input stream and release any system resources associated with the stream;
// Once the stream has been closed, an IOException is thrown for further read (), available (), reset (), or skip () calls;
// Closing the previously closed stream has no effect. Public void close () throws IOException {byte [] buffer; while (buffer = buf )! = Null) {if (bufUpdater. compareAndSet (this, buffer, null) {InputStream input = in; in = null; if (input! = Null) input. close (); return;} // in other cases, a new buffer is reloaded and the fill () method is called ;}}}
This is relatively simple. It's similar to the api. If you have time, you should check the source code to find out why ~