1. 程式人生 > 實用技巧 >IO 和NIO的區別

IO 和NIO的區別

1.IO和NIO的區別

NIO就是New IO在JDK1.4中引入。

IO和NIO有相同的作用和目的,但實現方式不同,NIO主要用到的是塊,所以NIO的效率要比IO快不少。

在Java API中提供了兩套NIO,一套針對標準輸入輸出NIO,另一套就是網路程式設計IO。

IONIO
面向流面向緩衝
阻塞IO非阻塞IO
選擇器

###① 面向流和麵向緩衝區

  1. Java IO 是面向流的而Java NIO是面向緩衝區的,就如同一個的重點在於過程,另一重點在於一個有一個階段。

    在Java IO中讀取資料和寫入資料是面向流(Stream)的,就如同河流一樣。所有的資料不停地向前的流淌,我們只能觸碰到當前的流水。

    如果需要獲取某個資料的前一項或後一項資料那就必須自己快取資料(將水從河流中打出來),而不能直接從流中獲取(因為面向流就意味著我們只有一個數據流的切面)

  2. Java NIO中資料的讀寫是面向緩衝區(Buffer)的,讀取時可以將整塊的資料讀取到緩衝區中,在寫入時則可以將整個緩衝區中的資料一起寫入。

    這就好像是在河流上建立水壩,面向流的資料讀寫只提供了一個數據流切面,而面向緩衝區的IO則使我們能夠看到所有的水(資料的上下文),也就是說在緩衝區中獲取某項資料的前一項資料或者是後一項資料十分方便。這種便利是有代價的,因為我們必須管理好緩衝區,這包括不能讓新的資料覆蓋了緩衝區中還沒有被處理的有用資料;將緩衝區中的資料正確的分塊,分清哪些被處理過哪些還沒有等等。

##② 阻塞和非阻塞

  1. Java IO是阻塞的,如果在一次讀寫資料呼叫時資料還沒有準備好,或者目前不可寫,那麼讀寫操作就會被阻塞直到資料準備好或目標可寫為止

  2. Java NIO則是非阻塞的,每一次資料讀寫呼叫都會立即返回,並將目前可讀(或可寫)的內容寫入緩衝區或者從緩衝區中輸出,即使當前沒有可用資料,呼叫仍然會立即返回並且不對緩衝區做任何操作。

    舉個例子:

    IO和NIO去超市買東西,如果超市中沒有需要的商品或者數量還不夠, IO會一直等到超市中需要的商品數量足夠了就將所有需要的商品帶回來。Java NIO則不同,不論超市中有多少需要的商品,它都將有需要的商品,立即全部買下並返回,甚至是沒有需要的商品也會立即返回。

    IO 要求一次完成任務,NIO允許多次完成任務

2.IO和NIO的適用場景

NIO是為彌補傳統IO的不足而誕生的,但是NIO也有缺陷,應為NIO是面向緩衝區的操作,每一次的資料處理都是對緩衝區進行的,那就必須注意:在資料處理之前必須要判斷緩衝區的資料是否完整或者已經讀取完畢。如果沒有,假設資料只讀取了一部分,那麼對不完整的資料處理沒有任何意義。所以每次資料處理之前都要檢測緩衝區。

注意:每次要進行資料處理必須保證資料已經準備完畢,但資料處理可以有多次。

IO和NIO各自使用場景:

IO:少量的連線,這些連線每次都要傳送大量的資料。

NIO:需要管理同時開啟的成千上萬個連線,而這些連結每次只發送少量的資料,例如聊天伺服器

##IO和NIO的工作流程

Java IO 工作流程

由於Java IO是阻塞的,所以當面對多個流的讀寫時需要多個執行緒處理。例如在網路IO中,Server端使用一個執行緒監聽一個埠,一旦某個連線被accept,建立新的執行緒來處理新建立的連線。
在這裡插入圖片描述

其中 read/write 是阻塞的。

Java NIO 工作流程

Java NIO 提供 Selector 實現單個執行緒管理多個channel的功能。
在這裡插入圖片描述

其中select 呼叫可能是阻塞的,也可以是非阻塞的。但是read/write是非阻塞的!

借鑑文章的文章-知行流浪