Java之Buffer屬性案例詳解
熟悉NIO的人想必一定不會(huì)陌生buffer中position,limit,capacity這三個(gè)屬性吧,之前在學(xué)習(xí)的時(shí)候遇到一個(gè)問題:就是當(dāng)你先往緩沖區(qū)寫入一部分?jǐn)?shù)據(jù),然后調(diào)用flip()方法,再全部讀取完數(shù)據(jù),然后再調(diào)用flip()方法,此時(shí)這三個(gè)值的變化是怎樣的,研究了一下,決定寫下來分享一下。
二、正文1、介紹 position: 它指的是下一次讀取或?qū)懭氲奈恢谩? limit: 指定還有多少數(shù)據(jù)需要寫出(在從緩沖區(qū)寫入通道時(shí)),或者還有多少空間可以讀入數(shù)據(jù)(在從通道讀入緩沖區(qū)時(shí)),它初始化是與capacity的值一樣,當(dāng)調(diào)用flip()方法之后,它的值會(huì)改變成position的值,而position被置0。它箭頭所指的位置是最后一位元素的下一位所在的位置* capacity: 指定了可以存儲(chǔ)在緩沖區(qū)中的最大數(shù)據(jù)容量,實(shí)際上,它指定了底層數(shù)組的大小,或者至少是指定了準(zhǔn)許我們使用的底層數(shù)組的容量,這個(gè)初始化后就不會(huì)再改變了。2、圖示以上三個(gè)屬性值之間有一些相對大小的關(guān)系:0 <= position <= limit <= capacity。如果我們創(chuàng)建一個(gè)新的容量大小為7的ByteBuffer對象,在初始化的時(shí)候,position設(shè)置為0,limit和 capacity被設(shè)置為7,在以后使用ByteBuffer對象過程中,capacity的值不會(huì)再發(fā)生變化,而其它兩個(gè)個(gè)將會(huì)隨著使用而變化。三個(gè)屬性值分別如圖所示:
初始化:
假設(shè)我們現(xiàn)在要往這個(gè)緩沖區(qū)里面寫入3個(gè)字節(jié),寫完之后,position的箭頭就會(huì)指向3的位置,而limit不變:
此時(shí)我們想從緩沖區(qū)讀取這3個(gè)字節(jié),就必須調(diào)用flip()方法,調(diào)用了flip()方法過后,limit置為position的位置,而position被置為0,也正應(yīng)證了上面所說的,position它指的是下一次讀取或?qū)懭氲奈恢茫琹imit它箭頭所指的位置是最后一位元素的下一位所在的位置:
現(xiàn)在我們可以調(diào)用get()方法,一直從緩沖區(qū)里面取數(shù)據(jù),直到取完為止,也就是當(dāng)position與limit的值一樣時(shí),就取完了:
這一次簡單的讀寫操作就完成了,如果想恢復(fù)成初始狀態(tài)的話,可以調(diào)用clear()方法:
之前學(xué)到這里的時(shí)候有個(gè)疑問,不知道大家想過沒有,就是我們在調(diào)用了get()方法從緩沖區(qū)取完里面的數(shù)據(jù),立馬去調(diào)用flip()方法,那這三個(gè)屬性的值會(huì)是什么變化?如果當(dāng)我只讀了2個(gè)字節(jié)的數(shù)據(jù)之后,就不讀了,然后再去調(diào)用flip(),這三個(gè)值又會(huì)是怎么變化?其實(shí)不管怎么繞,你只要懂得原理,就不難,咱們先看flip()源代碼做了什么:
public final Buffer flip() {limit = position;position = 0;mark = -1;return this; }
這里不難發(fā)現(xiàn),調(diào)用flip()方法,無非就是給這幾個(gè)變量賦值,將當(dāng)前的position值賦給limit,然后將position的值置為0,Mark是一個(gè)標(biāo)志變量,咱們以后會(huì)提到。熟悉以上代碼就不難解決我提出的2個(gè)問題:
當(dāng)你讀取完調(diào)用flip()的方法 positon:0 limit:3 capacity:7 當(dāng)你讀取2個(gè)字節(jié)之后調(diào)用flip()方法 positon:0 limit:2 capacity:7這里就解決了我之前遇到的這三個(gè)屬性值變化的問題!!!
三、測試代碼讀取完調(diào)用flip:
package com.cing.nio; import java.io.FileInputStream;import java.nio.Buffer;import java.nio.ByteBuffer;import java.nio.channels.FileChannel; public class NioTest1 { public static void main(String[] args) throws Exception{ FileInputStream fis = new FileInputStream('D:A.txt');FileChannel fc = fis.getChannel(); ByteBuffer buffer = ByteBuffer.allocate(7);output('初始化', buffer); fc.read(buffer);output('調(diào)用READ方法', buffer); buffer.flip();output('第一次調(diào)用flip', buffer); while (buffer.remaining() > 0) { byte b = buffer.get();}output('get()', buffer); buffer.flip();output('第二次flip', buffer); fis.close(); } public static void output(String step, Buffer buffer) {System.out.println(step + ' : ');System.out.println('buffer: ' + buffer + ', '); }}
輸出結(jié)果為:
初始化 : buffer: java.nio.HeapByteBuffer[pos=0 lim=7 cap=7], 調(diào)用READ方法 : buffer: java.nio.HeapByteBuffer[pos=3 lim=7 cap=7], 第一次調(diào)用flip : buffer: java.nio.HeapByteBuffer[pos=0 lim=3 cap=7], get() : buffer: java.nio.HeapByteBuffer[pos=3 lim=3 cap=7], 第二次flip : buffer: java.nio.HeapByteBuffer[pos=0 lim=3 cap=7],
讀取2字節(jié)之后調(diào)用flip:
package com.cing.nio; import java.io.FileInputStream;import java.nio.Buffer;import java.nio.ByteBuffer;import java.nio.channels.FileChannel; public class NioTest1 { public static void main(String[] args) throws Exception{ FileInputStream fis = new FileInputStream('D:A.txt');FileChannel fc = fis.getChannel(); ByteBuffer buffer = ByteBuffer.allocate(7);output('初始化', buffer); fc.read(buffer);output('調(diào)用READ方法', buffer); buffer.flip();output('第一次調(diào)用flip', buffer); while (buffer.remaining() > 1) { byte b = buffer.get();}output('get()', buffer); buffer.flip();output('第二次flip', buffer); fis.close(); } public static void output(String step, Buffer buffer) {System.out.println(step + ' : ');System.out.println('buffer: ' + buffer + ', '); }}
輸出結(jié)果為:
初始化 : buffer: java.nio.HeapByteBuffer[pos=0 lim=7 cap=7], 調(diào)用READ方法 : buffer: java.nio.HeapByteBuffer[pos=3 lim=7 cap=7], 第一次調(diào)用flip : buffer: java.nio.HeapByteBuffer[pos=0 lim=3 cap=7], get() : buffer: java.nio.HeapByteBuffer[pos=2 lim=3 cap=7], 第二次flip : buffer: java.nio.HeapByteBuffer[pos=0 lim=2 cap=7],
NIO的知識(shí)學(xué)起來還是比較有趣的,期待下次與大家分享這塊的知識(shí)!
到此這篇關(guān)于Java之Buffer屬性案例詳解的文章就介紹到這了,更多相關(guān)Java之Buffer屬性內(nèi)容請搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!
相關(guān)文章:
1. 詳解CSS開發(fā)過程中的20個(gè)快速提升技巧2. 一篇文章帶你了解JavaScript-語句3. .Net Core使用Coravel實(shí)現(xiàn)任務(wù)調(diào)度的完整步驟4. 常見 PHP ORM 框架與簡單代碼實(shí)現(xiàn)5. asp讀取xml文件和記數(shù)6. XML 取得元素的字符數(shù)據(jù)7. Ajax實(shí)現(xiàn)動(dòng)態(tài)顯示并操作表信息的方法8. 如何使用ASP.NET Core 配置文件9. .Net core 的熱插拔機(jī)制的深入探索及卸載問題求救指南10. ASP+ajax實(shí)現(xiàn)頂一下、踩一下同支持與反對的實(shí)現(xiàn)代碼
