為了對后續(xù)關(guān)于 Mina 的 ProtocolFilter( 編解碼器 ) 的編寫有一個更好的理解,本文講述一下關(guān)于 Mina?ByteBuffer 和 Java?Nio?ByteBuffer 的區(qū)別。關(guān)于 Java?Nio?ByteBuffer 和 Mina?ByteBuffer 及其子類的類圖在附件中都已經(jīng)給出了。因為 Mina 的 ByteBuffer 在 Mina?2.0 以上的版本中都改稱 IoBuffer 。為了使后文關(guān)于 ByteBuffer 的名字不致混淆, Mina?ByteBuffer 都統(tǒng)稱 IoBuffer , Java?Nio?ByteBuffer 統(tǒng)稱 ByteBuffer 。關(guān)于 IoBuffer 中的對 ByteBuffer 擴展及一些重要的方法都在 IoBuffer 的類圖中用紅色方框標出。詳細的信息請參考附件中。
?
?
在開始對 IoBuffer 的討論前,先簡單的講述一下 ByteBuffer 的用法。 IoBuffer 是對 ByteBuffer 的一個封裝。 IoBuffer 中的很多方法都是對 ByteBuffer 的直接繼承。只是對 ByteBuffer 添加了一些擴展了更加實用的方法。
?
?
(1) ByteBuffer 簡介
ByteBuffer 繼承于 Buffer 類, ByteBuffer 中存放的是字節(jié),如果要將它們轉(zhuǎn)換成字符串則需要使用 Charset , Charset 是字符編碼。它提供了把字節(jié)流轉(zhuǎn)換成字符串 ( 解碼 ) 和將字符串轉(zhuǎn)換成字節(jié)流 ( 編碼 ) 的方法。這個和后面講述的 Mina 的編解碼的工作原理類似。對 ByteBuffer 的訪問可以使用 read() , write() 等方法。
?
?
ByteBuffer 有一下三個重要的屬性:
1)? 容量 (capacity) :表示該緩存區(qū)可以存放多少數(shù)據(jù)。
2)? 極限 (limit) :表示讀寫緩存的位置,不能對超過位置進行數(shù)據(jù)的讀或?qū)懖僮鳌?
位置 (position) :表示下一個緩存區(qū)的讀寫單元。每讀寫一次緩存區(qū),位置都會變化。位置是一個非負整數(shù)。
?
ByteBuffer 的這三個屬性相當于三個標記位,來表示程序可以讀寫的區(qū)域:
上圖簡單的表示了容量、極限、位置在緩存區(qū)中的位置。其中極限只能標記容量以內(nèi)的位置,即極限值的大小不能超過容量。同樣位置是用來標記程序?qū)彺鎱^(qū)進行讀或?qū)懖僮鞯拈_始位置。程序只能在極限以內(nèi)的范圍進行讀寫,即讀寫操作不能超過極限的范圍,所以位置值的大小也不能超過極限。三者的大小關(guān)系為:容量 > 極限 > 位置 >=0 。
?
上面說到 ByteBuffer 的三個屬性只是緩存區(qū)的標記位置。那么如何改變這些標記的位置呢? ByteBuffer 提供了一下三種方法來改變上面的屬性值。
1) clear(): 極限設(shè)置為容量,位置設(shè)為 0 。
2) flip(): 極限設(shè)為位置,位置設(shè)為 0 。
3)rewind(): 不改變極限,位置設(shè)為 0 。
// JDK沒有提供ByteBuffer的公開構(gòu)造方法只能通過該
// 方法來創(chuàng)建一個緩存區(qū)。
ByteBuffer buffer = ByteBuffer.allocate(1024);
// ========測試緩存讀寫一個字符串=======//
String userName ="chinaestone";
char[] charArray = userName.toCharArray();
System.out.println("這是往緩存中存放的 字符串");
for(int i=0;i<charArray.length;i++){
System.out.println(charArray[i]);
buffer.putChar(charArray[i]);
}
buffer.limit(buffer.position());
buffer.position(0);
System.out.println();
System.out.println("這是緩存中取出來的 字符串");
while(buffer.hasRemaining()){
System.out.println(buffer.getChar());
}
?
上面只是一個簡單的演示程序,功能是實現(xiàn)對字符串的讀寫,比較 “ 笨 ” ,呵呵。關(guān)于如何向 ByteBuffer 讀寫字符串會在 IoBuffer 中詳細講解。
?
(2) IoBuffer 簡介
IoBuffer 是對 ByteBuffer 的擴展,并不是和 ByteBuffer 毫無關(guān)系的。對 Mina 或者 Socket 應用來說, ByteBuffer 提供的方法存在一下不足:
1) 它沒有提供足夠可用的 put 和 set 方法,例如: fill 、 get/putString 、? get/putAsciiInt() 等。
2) 很難將可變長度的數(shù)據(jù)放入 ByteBuffer 。
基于以上的缺點, Mina 提供了 IoBuffer 來補充了 ByteBuffer 的不足之處。
?
Let's?drink?code, 來看看 Mina 的 IoBuffer 是如何讀寫字符串的。
// 獲取一個容量為1024字節(jié)的ByteBuffer
ByteBuffer buffer = ByteBuffer.allocate(1024);
// 設(shè)置系統(tǒng)字符集為utf-8
Charset ch =Charset.forName("utf-8");
// 獲取utf-8的編碼器
CharsetEncoder encoder = ch.newEncoder();
// 獲取utf-8的解碼器
CharsetDecoder decoder = ch.newDecoder();
System.out.println(buffer.remaining());
// 進行編碼的字符串
String cs = "中國壹石頭";
// 將字符串編碼后放入緩存
buffer.putString(cs,encoder);
System.out.println(buffer.remaining());
// 將緩存的位置設(shè)為位置
buffer.limit(buffer.position());
// 將緩存的位置設(shè)為0
buffer.position(0);
// 讀取緩存中的字符串
String str = buffer.getString(decoder);
// 打印輸出緩存中的信息
System.out.println(str);
System.out.println(buffer.remaining());
?
注意此處用到了 Charset ,它的作用在上面已經(jīng)說道,它主要用來進行編解碼的,因此對字符串進行編碼和解碼時注意要使用相同的編碼。
?
?
(3) IoBuffer 的子類
為了更好的使用 IoBuffer 進行開發(fā), IoBuffer 提供了兩個子類 BaseByteBuffer 和 ByteBufferProxy 。 BaseByteBuffer 實現(xiàn)了 IoBuffer 中定義的絕大多數(shù)方法。如果你在實際開發(fā)中要擴展適合于自己的方法時可以繼承該類,因為它可以使你的實現(xiàn)更加簡單。 ByteBufferProxy 中封裝了一個 IoBuffer ,所有對 ByteBuffer 的操作都可以通過該類提供的方法來實現(xiàn)。?
?
本文只是簡單的介紹了 IoBuffer 和 ByteBuffer 的基本知識,如果需要了解 IoBuffer 更多的信息請參考 Mina 的幫助文檔和 Mina 的源碼。
深入理解Apache Mina (6)---- Java Nio ByteBuffer與Mina ByteBuffer的區(qū)別
更多文章、技術(shù)交流、商務合作、聯(lián)系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元

