主要區別:
IO NIO
面向字節流 面向緩衝區
阻塞 基於Selector的非阻塞編程
Java IO 和 NIO的主要區別體如今以上兩個方面,如下詳細說明這些區別的具體含義。 面向流和麪向緩衝區 這個概念和編程方法中的面向過程、面向對象相似。Java IO 是面向流的而Java NIO是面向緩衝區的。 在Java IO中讀取數據和寫入數據是面向流(Stream)的,這表示當咱們從流中讀取數據,寫入數據時也將其寫入流,流的含義在於沒有緩存 ,就好像咱們站在流水線前,全部的數據沿着流水線依次到達咱們的面前,咱們只能讀取當前的數據(至關於咱們擁有一個數據流的切面)。若是須要獲取某個數據的前一項或後一項數據那就必須本身緩存數據,而不能直接從流中獲取(由於面向流就意味着咱們只有一個數據流的切面) 而在Java NIO中數據的讀寫是面向緩衝區(Buffer)的,讀取時能夠將整塊的數據讀取到緩衝區中,在寫入時則能夠將整個緩衝區中的數據一塊兒寫入。這就好像是將流水線傳輸變成了卡車運送,面向流的數據讀寫只提供了一個數據流切面,而面向緩衝區的IO則使咱們可以看到數據的上下文,也就是說在緩衝區中獲取某項數據的前一項數據或者是後一項數據十分方便。這種便利是有代價的,由於咱們必須管理好緩衝區,這包括不能讓新的數據覆蓋了緩衝區中尚未被處理的有用數據;將緩衝區中的數據正確的分塊,分清哪些被處理過哪些尚未等等。 Java NIO的IO模型與不少IO的本質更加一致!磁盤IO讀寫就是數據塊讀寫; TCP/IP協議傳輸的也是數據包而不是數據流。可是不少系統提供的是倒是面向流的系統API,例如套接字API是面向數據流的。 阻塞和非阻塞 Java IO是阻塞的,若是在一次讀寫數據調用時數據尚未準備好,或者目前不可寫,那麼讀寫操做就會被阻塞直到數據準備好或目標可寫爲止。Java NIO則是非阻塞的,每一次數據讀寫調用都會當即返回,並將目前可讀(或可寫)的內容寫入緩衝區或者從緩衝區中輸出,即便當前沒有可用數據,調用仍然會當即返回而且不對緩衝區作任何操做。這就好像去超市買東西,若是超市中沒有須要的商品或者數量還不夠,那麼Java IO會一直等直到超市中須要的商品數量足夠了就將全部須要的商品帶回來,Java NIO則不一樣,不論超市中有多少須要的商品,它都會當即買下能夠買到的全部須要的商品並返回,甚至是沒有須要的商品也會當即返回。 阻塞IO會使得線程將大量的時間浪費在等待IO上,這是很是不划算的,可是這種阻塞能夠在數據可用時當即獲取並處理數據,而非阻塞IO則必須經過重複的調用來獲取所有數據。 Java NIO 使用Selector實現單線程管理多個Channel,經過 select 調用,能夠獲取已經準備好的Channel並進行相應的處理。 Java IO 工做流程 因爲Java IO是阻塞的,因此當面對多個流的讀寫時須要多個線程處理。例如在網絡IO中,Server端使用一個線程監聽一個端口,一旦某個鏈接被accept,建立新的線程來處理新創建的鏈接。 其中 read/write 是阻塞的。 Java NIO 工做流程 Java NIO 提供 Selector 實現單個線程管理多個channel的功能。
其中select 調用多是阻塞的,也能夠是非阻塞的。可是read/write是非阻塞的!緩存
——本文轉自CSDN網絡