Java中IO和NIO的區(qū)別詳細解析
1.IO和NIO的區(qū)別
NIO就是New IO在JDK1.4中引入。
IO和NIO有相同的作用和目的,但實現(xiàn)方式不同,NIO主要用到的是塊,所以NIO的效率要比IO快不少。
在Java API中提供了兩套NIO,一套針對標準輸入輸出NIO,另一套就是網(wǎng)絡編程IO。
IO | NIO |
面向流 | 面向緩沖 |
阻塞IO | 非阻塞IO |
無 | 選擇器 |
面向流和面向緩沖區(qū)
- Java IO 是面向流的而Java NIO是面向緩沖區(qū)的,就如同一個的重點在于過程,另一重點在于一個有一個階段。
在Java IO中讀取數(shù)據(jù)和寫入數(shù)據(jù)是面向流(Stream)的,就如同河流一樣。所有的數(shù)據(jù)不停地向前的流淌,我們只能觸碰到當前的流水。
如果需要獲取某個數(shù)據(jù)的前一項或后一項數(shù)據(jù)那就必須自己緩存數(shù)據(jù)(將水從河流中打出來),而不能直接從流中獲?。ㄒ驗槊嫦蛄骶鸵馕吨覀冎挥幸粋€數(shù)據(jù)流的切面)
- Java NIO中數(shù)據(jù)的讀寫是面向緩沖區(qū)(Buffer)的,讀取時可以將整塊的數(shù)據(jù)讀取到緩沖區(qū)中,在寫入時則可以將整個緩沖區(qū)中的數(shù)據(jù)一起寫入。
這就好像是在河流上建立水壩,面向流的數(shù)據(jù)讀寫只提供了一個數(shù)據(jù)流切面,而面向緩沖區(qū)的IO則使我們能夠看到所有的水(數(shù)據(jù)的上下文),也就是說在緩沖區(qū)中獲取某項數(shù)據(jù)的前一項數(shù)據(jù)或者是后一項數(shù)據(jù)十分方便。這種便利是有代價的,因為我們必須管理好緩沖區(qū),這包括不能讓新的數(shù)據(jù)覆蓋了緩沖區(qū)中還沒有被處理的有用數(shù)據(jù);將緩沖區(qū)中的數(shù)據(jù)正確的分塊,分清哪些被處理過哪些還沒有等等。
阻塞和非阻塞
- Java IO是阻塞的,如果在一次讀寫數(shù)據(jù)調(diào)用時數(shù)據(jù)還沒有準備好,或者目前不可寫,那么讀寫操作就會被阻塞直到數(shù)據(jù)準備好或目標可寫為止。
- Java NIO則是非阻塞的,每一次數(shù)據(jù)讀寫調(diào)用都會立即返回,并將目前可讀(或可寫)的內(nèi)容寫入緩沖區(qū)或者從緩沖區(qū)中輸出,即使當前沒有可用數(shù)據(jù),調(diào)用仍然會立即返回并且不對緩沖區(qū)做任何操作。
舉個例子:
IO和NIO去超市買東西,如果超市中沒有需要的商品或者數(shù)量還不夠, IO會一直等到超市中需要的商品數(shù)量足夠了就將所有需要的商品帶回來。Java NIO則不同,不論超市中有多少需要的商品,它都將有需要的商品,立即全部買下并返回,甚至是沒有需要的商品也會立即返回。
IO 要求一次完成任務,NIO允許多次完成任務
2.IO和NIO的適用場景
NIO是為彌補傳統(tǒng)IO的不足而誕生的,但是NIO也有缺陷,應為NIO是面向緩沖區(qū)的操作,每一次的數(shù)據(jù)處理都是對緩沖區(qū)進行的,那就必須注意:在數(shù)據(jù)處理之前必須要判斷緩沖區(qū)的數(shù)據(jù)是否完整或者已經(jīng)讀取完畢。如果沒有,假設數(shù)據(jù)只讀取了一部分,那么對不完整的數(shù)據(jù)處理沒有任何意義。所以每次數(shù)據(jù)處理之前都要檢測緩沖區(qū)。
注意:每次要進行數(shù)據(jù)處理必須保證數(shù)據(jù)已經(jīng)準備完畢,但數(shù)據(jù)處理可以有多次。
IO和NIO各自使用場景:
IO:少量的連接,這些連接每次都要發(fā)送大量的數(shù)據(jù)。
NIO:需要管理同時打開的成千上萬個連接,而這些鏈接每次只發(fā)送少量的數(shù)據(jù),例如聊天服務器
IO和NIO的工作流程
Java IO 工作流程
由于Java IO是阻塞的,所以當面對多個流的讀寫時需要多個線程處理。例如在網(wǎng)絡IO中,Server端使用一個線程監(jiān)聽一個端口,一旦某個連接被accept,創(chuàng)建新的線程來處理新建立的連接。
其中 read/write 是阻塞的。
Java NIO 工作流程
Java NIO 提供 Selector 實現(xiàn)單個線程管理多個channel的功能。
其中select 調(diào)用可能是阻塞的,也可以是非阻塞的。但是read/write是非阻塞的!
到此這篇關于Java中IO和NIO的區(qū)別詳細解析的文章就介紹到這了,更多相關IO和NIO的區(qū)別內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
flyway實現(xiàn)java 自動升級SQL腳本的問題及解決方法
大家在平時開發(fā)自己寫SQL語句忘記在所有環(huán)境執(zhí)行,需要新增環(huán)境做數(shù)據(jù)遷移,那么遇到這樣的問題該如何解決呢?本文通過場景分析給大家介紹java 自動升級SQL腳本的策略,感興趣的朋友一起看看吧2021-07-07Spring中的@ControllerAdvice三種用法詳解
這篇文章主要介紹了Spring中的@ControllerAdvice三種用法詳解,加了@ControllerAdvice的類為那些聲明了(@ExceptionHandler、@InitBinder或@ModelAttribute注解修飾的)方法的類而提供的<BR>專業(yè)化的@Component,以供多個Controller類所共享,需要的朋友可以參考下2024-01-01Java連接并操作Sedna XML數(shù)據(jù)庫的方法
這篇文章主要介紹了Java連接并操作Sedna XML數(shù)據(jù)庫的方法,較為詳細的說明了Sedna XML數(shù)據(jù)庫的原理與功能,并給出了基于java操作Sedna XML數(shù)據(jù)庫的方法,需要的朋友可以參考下2015-06-06Spring Boot 將yyyy-MM-dd格式的文本字符串直接轉換為LocalDateTime出現(xiàn)的問題
這篇文章主要介紹了Spring Boot 將yyyy-MM-dd格式的文本字符串直接轉換為LocalDateTime出現(xiàn)的問題,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-09-09微服務mybatis?typehandler使用詳解(就這一篇夠了)
TypeHandler是MyBatis框架的核心組件,實現(xiàn)數(shù)據(jù)庫表字段類型和Java?數(shù)據(jù)類型之間的相互轉換,本文介紹通過實例代碼mybatis?typehandler使用,感興趣的朋友一起看看吧2024-02-02