IO與NIO,AIO

IO(同步阻塞)

  • IO流分類:

    • 字符流:Reader,Writer

    • 字節(jié)流:InputStream,OutputStream

img

注意:對于字節(jié)流的輸入輸出是相對于java平臺來說的,所以當(dāng)要讀取文件時,相當(dāng)于將文件內(nèi)容輸入到j(luò)ava平臺,所以要用InputStream,寫入文件時,相當(dāng)于將文件內(nèi)容從java平臺輸出到文件中,所以要用OutputStream.

  • 字符流操作的注意事項(xiàng):

    • 寫入文件必須要用flush()刷新

    • 用完一定要記得關(guān)閉流

    • 創(chuàng)建一個文件時,如果該目錄下有同名文件,將被覆蓋

    • 在讀取文件時,必須保證該文件已存在,否則拋出異常

    • 字符流的緩沖區(qū)的出現(xiàn)是為了提高流的操作效率而出現(xiàn)的

    • 需要被提高效率的流作為參數(shù)傳遞給緩沖區(qū)的構(gòu)造函數(shù)

    • 在緩沖區(qū)中封裝了一個數(shù)組,存入數(shù)據(jù)后一次取出

  • 字節(jié)流操作的注意事項(xiàng)

    • 字節(jié)流操作可以不用刷新流操作

    • InputStream特有方法:int available()(返回文件中的字節(jié)個數(shù))

NIO( 多路復(fù)用 ,同步非阻塞)

  • 同步與異步(synchronous/asynchronous):同步(等待返回)是一種可靠的有序運(yùn)行機(jī)制,當(dāng)我們進(jìn)行同步操作時,后續(xù)的任務(wù)是等待當(dāng)前調(diào)用返回,才會進(jìn)行下一步;而異步(不等待,回調(diào))則相反,其他任務(wù)不需要等待當(dāng)前調(diào)用返回,通常依靠事件、回調(diào)等機(jī)制來實(shí)現(xiàn)任務(wù)間次序關(guān)系

  • 阻塞與非阻塞:在進(jìn)行阻塞操作時,當(dāng)前線程會處于阻塞狀態(tài),無法從事其他任務(wù),只有當(dāng)條件就緒才能繼續(xù),比如ServerSocket新連接建立完畢,或者數(shù)據(jù)讀取、寫入操作完成;而非阻塞則是不管IO操作是否結(jié)束,直接返回,相應(yīng)操作在后臺繼續(xù)處理

  • 很多時候,人們也把 java.net下面提供的部分網(wǎng)絡(luò) API,比如 Socket、ServerSocket、HttpURLConnection 也歸類到同步阻塞 IO 類庫,因?yàn)榫W(wǎng)絡(luò)通信同樣是 IO 行為。

  • 三個組成部分:

    • Channel :管道

      • 通過它讀取和寫入數(shù)據(jù)??梢园阉醋鍪荌O中的流 ,但是Channel是雙向的,,既可以讀又可以寫,而流是單向的

      • Channel可以進(jìn)行異步的讀寫

      • 對Channel的讀寫必須通過buffer對象

      • Channel 類型

        • FileChannel:從文件讀取數(shù)據(jù)的

        • DatagramChannel:讀寫UDP網(wǎng)絡(luò)協(xié)議數(shù)據(jù)

        • SocketChannel:讀寫TCP網(wǎng)絡(luò)協(xié)議數(shù)據(jù)

        • ServerSocketChannel:可以監(jiān)聽TCP連接

    • buffer:緩沖區(qū)

      • 所有數(shù)據(jù)都通過Buffer對象處理,所以,永遠(yuǎn)不會將字節(jié)直接寫入到Channel中,相反,是將數(shù)據(jù)寫入到Buffer中;同樣,也不會從Channel中讀取字節(jié),而是將數(shù)據(jù)從Channel讀入Buffer,再從Buffer獲取這個字節(jié)

      • NIO讀寫數(shù)據(jù)的中轉(zhuǎn)池。Buffer實(shí)質(zhì)上是一個數(shù)組,通常是一個字節(jié)數(shù)據(jù),但也可以是其他類型的數(shù)組。但一個緩沖區(qū)不僅僅是一個數(shù)組,重要的是它提供了對數(shù)據(jù)的結(jié)構(gòu)化訪問,而且還可以跟蹤系統(tǒng)的讀寫進(jìn)程。

      • 使用 Buffer 讀寫數(shù)據(jù) 的四個步驟

        1.寫入數(shù)據(jù)到 Buffer, Buffer 會記錄下寫了多少數(shù)據(jù) ;

        2.調(diào)用 flip() 方法, 將 Buffer 切換模式;

        3.從 Buffer 中讀取數(shù)據(jù), 可以讀取之前寫入到 Buffer 的所有數(shù)據(jù)。 ;

        4.調(diào)用 clear() 方法或者 compact() 方法, 清空緩沖區(qū),讓它可以再次被寫入。有兩種方式能清空緩沖區(qū):調(diào)用 clear() 或 compact() 方法。clear() 方法會清空整個緩沖區(qū)。compact() 方法只會清除已經(jīng)讀過的數(shù)據(jù)。任何未讀的數(shù)據(jù)都被移到緩沖區(qū)的起始處,新寫入的數(shù)據(jù)將放到緩沖區(qū)未讀數(shù)據(jù)的后面。

      • buffer分類:

        • ByteBuffer

        • CharBuffer

        • DoubleBuffer

        • FloatBuffer

        • IntBuffer

        • LongBuffer

        • ShortBuffer

    • Selector

      • Selector是一個對象,它可以注冊到很多個Channel上,監(jiān)聽各個Channel上發(fā)生的事件,并且能夠根據(jù)事件情況決定Channel讀寫。這樣,通過一個線程管理多個Channel,就可以處理大量網(wǎng)絡(luò)連接了。 在高并發(fā)中還可以減少線程的占用,和切換線程上下文的消耗

      • 注冊一個channel到selector上

Selector selector = Selector.open();
channel.configureBlocking(false);
SelectionKey key =channel.register(selector,SelectionKey.OP_READ);
//op_READ :注冊對各種 I/O 事件興趣的地方,

注意: 注冊的Channel 必須設(shè)置成異步模式 才可以,否則異步IO就無法工作,這就意味著我們不能把一個FileChannel注冊到Selector,因?yàn)镕ileChannel沒有異步模式,但是網(wǎng)絡(luò)編程中的SocketChannel是可以的。 、

  • 請注意對register()的調(diào)用的返回值是一個SelectionKey。 SelectionKey 代表這個通道在此 Selector 上注冊。當(dāng)某個 Selector 通知您某個傳入事件時,它是通過提供對應(yīng)于該事件的 SelectionKey 來進(jìn)行的。SelectionKey 還可以用于取消通道的注冊。

NIO多路復(fù)用

主要步驟和元素:

  • 首先,通過 Selector.open() 創(chuàng)建一個 Selector,作為類似調(diào)度員的角色。
  • 然后,創(chuàng)建一個 ServerSocketChannel,并且向 Selector 注冊,通過指定 SelectionKey.OP_ACCEPT,告訴調(diào)度員,它關(guān)注的是新的連接請求。
  • Selector 阻塞在 select 操作,當(dāng)有 Channel 發(fā)生接入請求,就會被喚醒。
  • 在 具體的 方法中,通過 SocketChannel 和 Buffer 進(jìn)行數(shù)據(jù)操作

IO 都是同步阻塞模式,所以需要多線程以實(shí)現(xiàn)多任務(wù)處理。而 NIO 則是利用了單線程輪詢事件的機(jī)制,通過高效地定位就緒的 Channel,來決定做什么,僅僅 select 階段是阻塞的,可以有效避免大量客戶端連接時,頻繁線程切換帶來的問題,應(yīng)用的擴(kuò)展能力有了非常大的提高

雖然NIO在網(wǎng)絡(luò)操作中,提供了非阻塞的方法,但是NIO的IO行為還是同步的。對于NIO來說,我們的業(yè)務(wù)線程是在IO操作準(zhǔn)備好時,得到通知,接著就由這個線程自行進(jìn)行IO操作,IO操作本身是同步的。

AIO

對AIO來說,則更加進(jìn)了一步,它不是在IO準(zhǔn)備好時再通知線程,而是在IO操作已經(jīng)完成后,再給線程發(fā)出通知。因此AIO是不會阻塞的,此時我們的業(yè)務(wù)邏輯將變成一個回調(diào)函數(shù),等待IO操作完成后,由系統(tǒng)自動觸發(fā)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • # Java NIO # Java NIO屬于非阻塞IO,這是與傳統(tǒng)IO最本質(zhì)的區(qū)別。傳統(tǒng)IO包括socket和文...
    Teddy_b閱讀 723評論 0 0
  • Java NIO(New IO)是從Java 1.4版本開始引入的一個新的IO API,可以替代標(biāo)準(zhǔn)的Java I...
    JackChen1024閱讀 7,957評論 1 143
  • IO流(同步、阻塞) 、 NIO(同步、非阻塞) 、 NIO2(異步、非阻塞) 概述在我們學(xué)習(xí)Java的IO流之前...
    李明燚閱讀 326評論 0 1
  • 簡介 Java NIO 是由 Java 1.4 引進(jìn)的異步 IO.Java NIO 由以下幾個核心部分組成: Ch...
    永順閱讀 1,856評論 0 15
  • NIO概述 Java NIO全稱為Non-blocking IO或者New IO,從名字我們知道NIO是非阻塞的I...
    zhong0316閱讀 766評論 0 7

友情鏈接更多精彩內(nèi)容