《精通併發與Netty》學習筆記(09 - Java中流的概念)

Java中流的概念java

java程序經過流來完成輸入/輸出。流是生產或消費信息的抽象。流經過java的輸入/輸出與物理設備連接。儘管與它們連接的物理設備不盡相同,全部流的行爲具備一樣的方式。這樣,相同的輸入/輸出類和方法適用於全部類型的外部設備。這意味着一個輸入流可以抽象
多種不一樣類型的輸入:從磁盤文件,從鍵盤或從網絡套接字。一樣,一個輸出流能夠輸出到控制檯、磁盤文件或相連的網絡。流是處理輸入/輸出的一個潔淨的方法,例如它不須要代碼理解鍵盤和網絡的不一樣。java中流的實現是在java.io包定義的類層次結構內部的。數組

輸入/輸出流的概念
輸入/輸出時,數據在通訊通道中流動。所謂「數據流(stream)」指的是全部數據通訊通道之中,數據的起點和終點。信息的通道就是一個數據流。只要是數據從一個地方「流」到另一個地方,這種數據流動的通道均可以稱爲數據流。
輸入/輸出是相對於程序來講的。程序在使用數據時所扮演的角色有兩個:一個是源,一個是目的。
若程序是數據流的源,即數據的提供者,這個數據流對程序來講就是一個「輸出數據流」(數據從程序流出)。若程序是數據流的終點,這個數據流對程序而言就是一個「輸入數據流」(數據從程序外流向程序)網絡

輸入流:全部輸入流類都是 InputStream 抽象類(字節輸入流)和 Reader 抽象類(字符輸入流)的子類。其中 InputStream 類是字節輸入流的抽象類,是全部字節輸入流的父類,其層次結構如圖編碼

InputStream 類中全部方法遇到錯誤時都會引起 IOException 異常。以下是該類中包含的經常使用方法。
int read():從輸入流讀入一個 8 字節的數據,將它轉換成一個 0~255 的整數,返回一個整數,若是遇到輸入流的結尾返回 -1。
int read(byte[] b):從輸入流讀取若干字節的數據保存到參數 b 指定的字芳數組中,返回的字芾數表示讀取的字節數,若是遇到輸入流的結尾返回 -1。
int read(byte[] b,int off,int len):從輸入流讀取若干字節的數據保存到參數 b 指定的字節數組中,其中 off 是指在數組中開始保存數據位置的起始下標,len 是指讀取字節的位數。返回的是實際讀取的字節數,若是遇到輸入流的結尾則返回 -1。
void close():關閉數據流,當完成對數據流的操做以後須要關閉數據流。
int available():返回能夠從數據源讀取的數據流的位數。
skip(long n):從輸入流跳過參數 n 指定的字節數目。
boolean markSupported():判斷輸入流是否能夠重複讀取,若是能夠就返回 true。
void mark(int readLimit):若是輸入流能夠被重複讀取,從流的當前位置開始設置標記,readLimit 指定能夠設置標記的字苟數。
void reset():使輸入流從新定位到剛纔被標記的位置,這樣能夠從新讀取標記過的數據。spa

上述最後 3 個方法通常會結合在一塊兒使用,首先使用 markSupported() 判斷,若是能夠重複讀取,則使用 mark(int readLimit) 方法進行標記,標記完成以後可使用 read() 方法讀取標記範圍內的字節數,最後使用 reset() 方法使輸入流從新定位到標記的位置,繼而完成重複讀取操做。線程

Java 中的字符是 Unicode 編碼,即雙字節的,而 InputerStream 是用來處理單字節的,在處理字符文本時不是很方便。這時可使用 Java 的文本輸入流 Reader 類,該類是字符輸入流的抽象類,即全部字輸入流的實現都是它的子類。code

Reader類的具體層次結構如圖下 所示,該類的方法與 InputerSteam 類的方法相似,這裏再也不介紹。對象

輸出流:在 Java 中全部輸出流類都是 OutputStream 抽象類(字節輸出流)和 Writer 抽象類(字符輸出流)的子類。其中 OutputStream 類是字節輸出流的抽象類,是全部字節輸出流的父類,其層次結構如圖 blog

 

OutputStream 類是全部字節輸出流的超類,用於以二進制的形式將數據寫入目標設備,該類是抽象類,不能被實例化。OutputStream 類提供了一系列跟數據輸出有關的方法,以下所示。
int write (b):將指定字節的數據寫入到輸出流。
int write (byte[] b):將指定字節數組的內容寫入輸出流。
int write (byte[] b,int off,int len):將指定字節數組從 off 位置開始的 len 字芳的內容寫入輸出流。
close():關閉數據流,當完成對數據流的操做以後須要關閉數據流。
flush():刷新輸出流,強行將緩衝區的內容寫入輸出流。ip

字符輸出流的父類是 Writer,其層次結構如圖

輸入/輸出類

  • 在java.io包中提供了60多個類(流)
  • 從功能上分爲兩大類:輸入流和輸出流
  • 從流結構上分爲字節流(以字節爲處理單位或稱面向字節)和字符流(以字符爲處理單位或稱面向字符)

字節流的輸入流和輸出流基礎是InputStream和OutputStream這兩個抽象類,字節流的輸入輸出操做由這兩個類的子類實現,字符流是java1.1版後新增長的以字符爲單位進行輸入輸出處理的流,字符流輸入輸出的基礎是抽象類Reader和Writer

  • 字節流,數據的處理以字節爲基本單位,每次讀寫8位二進制數(一個字節)。也稱爲二進制流。
  • 字符流,用於字符數據的處理,每次讀寫16位二進制數(兩個字節)。
  字節流 字符流
輸入 InputStream Reader
輸出 OutputStream Writer

 

 

 

NIO,和傳統Io有何區別

    咱們使用InputStream從輸入流中讀取數據時,若是沒有讀取到有效的數據,程序將在此處阻塞該線程的執行。其實傳統的輸入裏和輸出流都是阻塞式的進行輸入和輸出。 不只如此,傳統的輸入流、輸出流都是經過字節的移動來處理的(即便咱們不直接處理字節流,但底層實現仍是依賴於字節處理),也就是說,面向流的輸入和輸出一次只能處理一個字節,所以面向流的輸入和輸出系統效率一般不高。 
    從JDk1.4開始,java提供了一系列改進的輸入和輸出處理的新功能,這些功能被統稱爲新IO(NIO)。新增了許多用於處理輸入和輸出的類,這些類都被放在java.nio包及其子包下,而且對原io的不少類都以NIO爲基礎進行了改寫。新增了知足NIO的功能。 
    NIO採用了內存映射對象的方式來處理輸入和輸出,NIO將文件或者文件的一塊區域映射到內存中,這樣就能夠像訪問內存同樣來訪問文件了。經過這種方式來進行輸入/輸出比傳統的輸入和輸出要快的多。

JDk1.4使用NIO改寫了傳統Io後,傳統Io的讀寫速度和NIO差不了太多。下節將詳細討論NIO的知識

相關文章
相關標籤/搜索