Buffer and a byte stream using the principle of analysis BufferedInputStream

We usually often the files are read operations, such as using FileInputStream read operation, the efficiency is very low. For this purpose we can use the byte stream buffer BufferedInputStream to operate, the efficiency of reading will be greatly improved. In this we introduce the principles of how to use BufferedInputStream and analyze their work.

I. Introduction to use:

1.1 Definitions:

BufferedInputStream Advanced Stream is not directly manipulate files, only low-flow can be directly connected to the file, so need a lower stream socket, such as:

FileInputStream fis = new FileInputStream("test.txt");

BufferedInputStream bis = new BufferedInputStream(fis);

 

1.2 to read the file:

When reading, we generally use the read () method reads a cycle, such as to the end of the file is read, the read () method returns -1, for example:

 

int len = -1 ;
while ((len = bis.read ())! = - 1 ) { 
    System.out.println (only); 
}

 

 

 

By way loop to read, you can read a file is completed.

 

Second principle analysis:

 From the foregoing understanding of the use BufferedInputStream, and that is how it works? Here will come to understand the principle of source code analysis by the BufferedInputStream.

2.1 Firstly, properties, and constructors under BufferedInputStream of:

Properties are as follows:

// The default buffer size 8K 
Private  static  int DEFAULT_BUFFER_SIZE = 8192 ;
 / * maximum buffer size Integer.MAX_VALUE - 8, 8 is reduced due to the virtual machine reserves some header information in the array * / 
Private  static  int MAX_BUFFER_SIZE = Integer. MAX_VALUE -. 8 ;
 // buffer byte array definition data stored in the 
protected  volatile  byte buf [];
 // atoms properties updater, to ensure atomic updates buf 
Private  static  Final 
        AtomicReferenceFieldUpdater <BufferedInputStream, byte []> = bufUpdater 
        AtomicReferenceFieldUpdater .newUpdater 
        (BufferedInputStream. class ,  byte . [] class , "buf" );
 // buf byte array of the actual data size 
protected  int COUNT;
 // position to start reading of 
protected  int POS;
 // record the reading start position of the last 
protected  int markpos = -1 ;
 // maximum permitted advance is read 
protected  int marklimit;

 

Constructor as follows:

// to InputStream as parameters, the default buffer size 8K 
public BufferedInputStream (InputStream in) {
         the this (in, DEFAULT_BUFFER_SIZE); 
} 

// custom buffer size 
public BufferedInputStream (InputStream in, int size) {
         Super (in);
         IF (size <= 0 ) {
             the throw  new new an IllegalArgumentException ( "Buffer size <= 0" ); 
        } 
        buf = new new  byte [size]; 
}

 

2.2 Analysis Methods:

2.2.1.read () method of analysis:

// no parameter read () method 
public  the synchronized  int read () throws IOException {
         // if the reading start position is equal to or greater than the actual size of the buffer 
        IF (POS> = COUNT) {
             // is filled buffer 
            fill () ;
             // after filling, the reading position is equal to or greater than the actual size of the buffer, the read, return -1 
            IF (POS> = COUNT)
                 return -1 ; 
        } 
        // return the first byte in the buffer 
        return getBufIfOpen () [POS ++] & 0xFF ; 
}

 

 2.2.2.read1 (byte [] b, int off, int len) Analysis Method:

This method of byte array can be customized, and the position to start reading and the actual reading of the length of the source as follows:

 

Private  int Read1 ( byte [] B, int OFF, int len) throws IOException {
      // size readable 
        int Avail = COUNT - POS;
         // if the size is less than or equal to read 0 
        IF (Avail <= 0 ) {
              // if len is greater than or equal to the buffer size and the mark position is less than 0, then the reading of the length of the given 
             IF (len> = getBufIfOpen (). && markpos length <0 ) {
                  return getInIfOpen (). read (B, OFF, len); 
             } 
            // if otherwise, the default size read 
            Fill (); 
             Avail = COUNT - POS;
             // If the size is less than or equal to read, the read, return -1 
             IF (avail <= 0) return -1 ; 
         } 
         // take a smaller value between the avail and len 
         int CNT = (avail <len ?) Avail: len;
          // the byte array buffer starting from the position pos, length b is copied to the start byte array off for the content of cnt 
         System.arraycopy (getBufIfOpen (), pos, b, off, CNT);
          // reading position increases CNT 
         POS + = CNT;
          // returns the length of the read 
         return CNT; 
}

 

 

2.2.3.read (byte b [], int off, int len) Analysis Method:

public  the synchronized  int Read ( byte B [], int OFF, int len)
         throws IOException 
    { 
        // check whether the flow off 
        getBufIfOpen (); // the Check for Stream Closed
        // by "|" operation to ensure that off, len is greater than or equal to 0 , b.length greater than or equal to len + OFF 
        IF ((OFF | len | (OFF + len) | (to b.length - (OFF + len))) <0 ) {
             the throw  new new an IndexOutOfBoundsException (); 
        } the else  IF (len 0 == ) {
             return 0 ; 
        } 
        int= 0 n- ;
         // infinite loop, as long as the remaining contents to meet the length len, it can be read to ensure that each length len 
        for (;;) {
             // read length len bytes 
            int Nread Read1 = (B, + n-OFF, len - n-);
             IF (Nread <= 0 )
                 return ? (n-== 0) Nread: n-;
             // because the length of a byte array buffer 8192, assuming 800 len, is read 10 times Thereafter, the remaining buffer length is 192 bytes, the length of the first reading is 192, i.e. n-192, in this case, does not return to cycle again the cycle again, the first buffer is filled, then after reading the remaining 608 to 800 is read, the length 800 is returned. 
            n-+ = Nread;
             IF (n-> = len)
                 return n-;
             // IF Closed But Not Available bytes NO, return
            INPUT = the InputStream in;
             // if the input stream to the available buffer size is less than or equal to 0, then n returns 
            IF (! INPUT = null && input.available () <= 0 )
                 return n; 
        } 
}

 

2.2.4.fill () method of analysis:

fill () method is used to read data and fill the buffer.

Private  void Fill () throws IOException {
         // check whether the flow Close 
        byte [] = Buffer getBufIfOpen ();
         // Analyzing marker position is less than 0 
        IF (markpos <0 )
             // set to position 0, i.e., start position 
            pos = 0;             / * NO Mark: the throw Away The buffer * / 
        // If the position is greater than or equal to the buffer size, the following logical processing press 
        the else  IF (POS> = buffer.length)   / * NO Room left in buffer * / 
            IF (markpos> 0) {   / * CAN Early Part of the throw Away The Buffer * / 
                int SZ = POS - markpos;
                System.arraycopy(buffer, markpos, buffer, 0, sz);
                pos = sz;
                markpos = 0;
            } else if (buffer.length >= marklimit) {
                markpos = -1;   /* buffer got too big, invalidate mark */
                pos = 0;        /* drop buffer contents */
            } else if (buffer.length >= MAX_BUFFER_SIZE) {
                throw new OutOfMemoryError("Required array size too large");
            } else {            /* grow buffer */
                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)) {
                     // of Can not IF there WAS AN buf the replace the async use Close.
                     // Note: This Would need to BE IF changed the Fill ()
                     // IS Ever Made Accessible to Multiple Threads.
                     // But for now , The only Way CAS CAN iS Via Fail Close.
                     // Assert buf == null; 
                    the throw  new new IOException ( "Stream Closed" ); 
                } 
                Buffer = nbuf were; 
            } 
        // set the size of POS 
        COUNT = POS;
         // read length the default size of the data to the buffer, and returns the read length
        int n-getInIfOpen = () Read (Buffer, POS, buffer.length -. POS);
         IF (n-> 0 )
             // to set the count to a size of length 
            count + = n- POS; 
}

 

Guess you like

Origin www.cnblogs.com/allenjing/p/11330865.html