NIO中Buffer常用flip()方法

2020-10-22 11:00:31

NIO

NIO概述

Java NIO 由以下核心部分組成:

  • Channel通道
  • Buffer緩衝區
  • Selector選擇器

在Java NIO程式設計中,我們是面向緩衝區(Buffer)程式設計的,對緩衝區常常需要使用
java.nio.Buffer中的flip()方法

我們先來介紹一些什麼是Buffer

Buffer

  • 使用 Buffer 與 Channel 互動,資料從通道讀入緩衝區,或從緩衝區寫入通道。

  • 緩衝區本質上是一個可以寫入資料的記憶體塊,之後可以讀取資料。 Buffer 物件包裝了此記憶體塊,提供了一組方法,可以更輕鬆地使用記憶體塊。

Buffer通常的操作

  • 將資料寫入緩衝區

  • 呼叫 buffer.flip() 反轉讀寫模式

  • 從緩衝區讀取資料

  • 呼叫 buffer.clear() 或 buffer.compact() 清除緩衝區內容

Buffer的重要屬性

  • capacity : 容量緩衝區的容量,是它所包含的元素的數量。不能為負並且不能更改。

  • position :緩衝區的位置 是下一個要讀取或寫入的元素的索引。不能為負,並且不能大於 limit

  • limit : 緩衝區的限制,緩衝區的限制不能為負,並且不能大於 capacity

在這裡插入圖片描述

flip():Buffer有兩種模式,寫模式和讀模式。在寫模式下呼叫flip()之後,Buffer從寫模式變成讀模式。

那麼limit就設定成了position當前的值(即當前寫了多少資料),postion會被置為0,以表示讀操作從快取的頭開始讀,mark置為-1。

呼叫flip()方法之前,往緩衝區寫資料

在這裡插入圖片描述

呼叫flip()方法後,從寫模式變成讀模式

在這裡插入圖片描述

讓我們一起看一段程式碼:src/test/resources/index.html中的index.html的資料為abcdefg

在這裡插入圖片描述

首先,我們設定的緩衝區的大小為 4 個位元組的大小,當我們執行結果為:

在這裡插入圖片描述

在buffer.flip()方法執行之前,一直在寫資料,在buffer.flip()方法執行完之後,Buffer從寫模式變成讀模式,然後通過這句程式碼System.out.println(decoder.decode(buffer));列印出了資料為:abcd

1.flip呼叫之前,一直往緩衝區寫資料,由於緩衝區的大小為4個位元組,所以只能寫abcd,也就是程式碼中的結果

  • S1 : Pos: 4 Limit:4

在這裡插入圖片描述

2.flip呼叫之後,轉換為讀模式。Position變為0

  • 執行結果S2 : Pos: 0 Limit:4

在這裡插入圖片描述

3.Decode呼叫後,列印出結果abcd

  • S3 : Pos: 3 Limit:3

在這裡插入圖片描述

4.Clear 呼叫後

  • Position回到0的位置,但是Buffer沒有被清空(可以理解為abcd還存在)

在這裡插入圖片描述

  • 由於我們有7個資料,但是緩衝區的大小為4,所以我們需要執行兩遍程式碼

5.第二次read後(由於Buffer沒有被清空,所以d還存在)

  • S1 : Pos: 3 Limit:4

在這裡插入圖片描述

6. 第二次 flip呼叫之後

  • S2 : Pos: 0 Limit:3

在這裡插入圖片描述

7. 第二次Decode呼叫後

  • efg
  • S3 : Pos: 3 Limit:3

在這裡插入圖片描述

abcdefg 這條資料就被讀取出來了。

如果程式碼中buffer.flip()這個方法沒有執行,結果會出現什麼,話不多說,直接看結果

在這裡插入圖片描述

原來列印abcd的地方變成了空,沒有任何結果列印。

整體過程就是:

  • 寫資料

在這裡插入圖片描述

  • 沒有呼叫flip,Position還在原來的位置,Decode呼叫後,所以為空。

在這裡插入圖片描述

  • 第二次read後

在這裡插入圖片描述

  • 第二次Decode呼叫後

在這裡插入圖片描述

所以列印d