1. 程式人生 > >【Java】緩衝流如何提高效能

【Java】緩衝流如何提高效能

前言

        本文寫的粗糙,僅作於工作間隙的隨筆。

        傳統的Java IO是基於阻塞的,他的工作狀態就是“讀/寫,等待,讀/寫,等待······”。

        緩衝流有位元組和字元兩種,原理上幾乎差不讀,本處以位元組緩衝路來進行討論。

一、緩衝輸入流

        BufferedInputStream extends FileInputStream,緩衝流的設計思想是基於裝飾器設計模式的,需要在構造緩衝流的時候傳入一個節點流。

        緩衝輸入流為什麼能夠提高效率?

        簡單一句話就是空間換時間。read方法雖然是一個位元組一個位元組的返回資料,但是他實際上是一次就讀取了buf個位元組,然後從buf中返回給read方法,如果取光了,在read一次,如此往復。也就是說,採用了緩衝技術之後,緩衝流呼叫本地IO的次數變為file.length/buf.length,預設buf是8192個位元組,因此read方法的效能提高了約8192倍。當然這不是不需要花費代價的,花費的代價就是多消耗了8191個記憶體位元組。


        read(arr[])最終也是使用了read(arr[], int, int)方法,此處兩者合在一起介紹。

        採用了緩衝技術的read(arr)方法,如果arr.length>=buf.length,那麼將不會在使用buf,而是直接將磁碟上的資料填充到arr,這樣才能保證最好的效能,但是可能引入的風險是arr的大小沒有控制好,導致記憶體緊張;如果arr.length<buf.length,那麼還是依舊讀滿整個buf,然後從buf中將資料System.arrayCopy到arr中,沒有了再次讀取磁碟到buf,如此重複,實際上最終和磁碟互動的並不是BufferedInputStream,而是通過構造器注入的其他節點流的native read(arr[])來實現,程式碼較多,而且CSDN圖片抽風,就不再I貼出來了,自行觀賞原始碼吧!

二、緩衝輸出流

        BufferedOutputStream extends FileOutputStream。

        read(int)方法的思想還是空間換時間,使用緩衝技術,則每次都是寫buf,直到buf寫滿了才會把資料刷到磁碟(刷盤的過程是呼叫構造方法中傳入的節點流的write(arr[])來實現的,而不是直接呼叫native write(int)實現),沒有使用緩衝技術,那麼每個位元組都需要消耗本地的IO資源,寫一個位元組,使用一次IO資源,然後再阻塞再寫,如此重複。


        wirte(arr[])最終呼叫write(arr[], int, int),思想是將arr中的資料刷到磁碟。使用了緩衝流技術,如果arr.length>=buf.length,則直接將arr中的資料刷盤;如果arr.length<buf.length,則將資料寫入buf,直到buf寫滿了才會刷盤,刷盤的過程也是呼叫構造方法中傳入的節點流的write(arr[], int, int)完成。

三、總結

        緩衝流之所以能夠提高效能,主要是利用了在記憶體中開闢的buf空間來實現的,減少了直接消耗系統IO資源的次數,從而提高了效能。