InputStream、OutputStream、BufferedOutputStream源碼解析

The InputStream/OutputStream works with Bytes which are 8 bits.
read、write根上調用的是native方法

一、read

1.方法

/*
Reads a byte of data from this input stream.
@return:next byte of data(0-255),or -1 if end
*/
int read()

/*
Reads up to b.length bytes of data from this input stream into an array of bytes
@param:b the buffer into which the data is read.
@return:the total number of bytes read into the buffer(0-Integer.MAX_VALUE),
or -1
*/
int read(byte[] b)

/*
Reads up to len bytes of data from this input stream into an array of bytes
@param b:the buffer into which the data is read.
@param off:the start offset in the destination array b
@param len:the maximum number of bytes read.
@return:the total number of bytes read into the buffer(0-Integer.MAX_VALUE),
or -1
*/
int read(byte[] b,int off,int len)

 /*
Returns an estimate of the number of remaining bytes that can be read (or
skipped over) from this input stream  
@return:an estimate of the number of remaining bytes that can be read
(or skipped over) from this input stream without blocking.
 */
int available()

/*
Closes this file input stream and releases any system resources
associated with the stream.
*/
void close()

2.實例

在這裏插入圖片描述

//讀
		FileInputStream fis=new FileInputStream("fos.txt");
		
		System.out.println("-----------讀的第一種方法----------");
		//一個字節一個字節的讀:read()方法
		/*int num=0;
		while ((num=fis.read())!=-1) {
			System.out.println((char)num);
		}
		fis.close();
		*/
		
		System.out.println("-----------讀的第二種方法----------");
		//字節數組的讀read(byte[] b)
		/*byte[] buf=new byte[1024];
		int len=0;
		while((len=fis.read(buf))!=-1) {
			System.out.println(new String(buf,0,len));
		}
		fis.close();
		*/
		
		System.out.println("-----------讀的第三種方法----------");
		// TODO Auto-generated method stub
		FileInputStream fis=new FileInputStream("fos.txt");
 
		int len1=fis.available();//返回字節數
		System.out.println(len1);
		byte[] buf1=new byte[len1];//定義一個剛剛好的緩衝區,因爲已經知道長度了,無需循環
	    fis.read(buf1);
	    fis.close();
	    //將所有的數據存入數組
	    //read(byte[]):從此輸入流中將最多 b.length 個字節的數據讀入一個 byte 數組中。 
	    //這個方法完成了兩件事情:1:將字符字節流中的數據放入字符數組中2:返回存入的字節長度
	     System.out.println(new String(buf1));		

涉及到利用byte[]構建String

String(byte[] bytes)
String(byte[] bytes,  int offset, int length) //offset:第一個 byte 的索引         

二、write

1.方法

在這裏插入圖片描述

/*
Flushes this output stream and forces any buffered output bytes
to be written out. 
*/
void flush()

2.實例

FileOutputStream fos=new FileOutputStream("fos.txt");
		
fos.write("abcde".getBytes());//不用刷新,write是直接寫入文件
		
fos.close();//雖然不刷新,但是得關資源

三、BufferedOutputStream

BufferedOutputStream在Java Program和Data Sink添加個buffer[]、BufferedInputStream是在Data Source和Java Program添加個buffer[]。原理類似,這裏對BufferedOutputStream源碼分析,加深對buffer理解。

1. 構造方法

   
    //The internal buffer where data is stored.
    protected byte buf[];

    //The number of valid bytes in the buffer. 
    protected int count;

   
    public BufferedOutputStream(OutputStream out) {
        this(out, 8192);//默認size是8192
    }

    /*
     @param   out    the underlying output stream.
     @param   size   the buffer size.
     
    */
    public BufferedOutputStream(OutputStream out, int size) {
        super(out);//FilterOutputStream(OutputStream out)
        if (size <= 0) {
            throw new IllegalArgumentException("Buffer size <= 0");
        }
        buf = new byte[size];
    }

2. write

When you write data to a Java BufferedOutputStream the data is cached internally in a byte buffer until the byte buffer is full, at which time the whole buffer is written to the underlying OutputStream.
在這裏插入圖片描述

   //從父類FilterOutputStream繼承過來的變量
   protected OutputStream out;
   
    /** Flush the internal buffer */
    private void flushBuffer() throws IOException {
        if (count > 0) {
            out.write(buf, 0, count);
            count = 0;
        }
    }

   
    public synchronized void write(int b) throws IOException {
        if (count >= buf.length) {
            flushBuffer();
        }
        buf[count++] = (byte)b;
    }

   
    public synchronized void write(byte b[], int off, int len) throws IOException {
    
        //①將buf刷入文件 ②將b直接刷入文件(避免多次刷入) 順序不能顛倒,否則文件會出錯
        if (len >= buf.length) {
            flushBuffer();
            out.write(b, off, len);
            return;
        }
        
        //buf.length>len>buf剩餘空間
        if (len > buf.length - count) {
            flushBuffer();
        }
        
        /*arraycopy(Object src,int srcPos,Object dest,int destPos,int length)
        源數組中位置在 srcPos 到 srcPos+length-1 之間的組件被分別複製到
        目標數組中的 destPos到destPos+length-1 位置。 
        */
        System.arraycopy(b, off, buf, count, len);
        count += len;
    }

    /*
      Flushes this buffered output stream. This forces any buffered
     output bytes to be written out to the underlying output stream.
     */
    public synchronized void flush() throws IOException {
        flushBuffer();
        out.flush();//若out是FileOutputStream,則會調用其父類OutputStream的flush()
                   //它是個空方法,並沒有做任何事情。
    }
    
   /*從父類FilterOutputStream繼承過來的 try-with-resource 會在try後,調用out的close方法
     這個方法執行兩個操作①flush  ②out.close()
     若BufferedOutputStream對象調用了close,則無需輸出流OutputStream再調用close
   */
   public void close() throws IOException {
         try (OutputStream ostream = out) {
            flush();//也就是說即使buf不滿,在flushBuffer關閉時,也會將buf刷入流中
        }
    }

理解 try (OutputStream ostream = out):深入理解 Java try-with-resource 語法糖

flush()調用:
If you want to make sure that all written data is written to disk without having to close the BufferedOutputStream you can call its flush() method. Calling flush() will make sure that all data which has been written to the BufferedOutputStream so far, is fully written to the underlying OutputStream too, plus flush() will also have been called on the underlying OutputStream.
在沒有close()時,將buff[]數據刷入流中。

3.測試

FileOutputStream fos=new FileOutputStream("C:\\Users\\ASUS\\Desktop\\tmp.txt");
BufferedOutputStream bos=new BufferedOutputStream(fos);
bos.write(1);
bos.close();
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章