翻譯為緩沖,是一塊可以讀寫的區(qū)域。
思考:沒有buffer之前的讀寫。
方法抽象方法
//是否只讀
public abstract boolean isReadOnly();
//判斷有沒有數(shù)組
public abstract boolean hasArray();
//返回?cái)?shù)組
public abstract Object array();
//返回?cái)?shù)組偏移
public abstract int arrayOffset();
//是否是直接緩沖區(qū)
public abstract boolean isDirect();
//切分
public abstract Buffer slice();
//切分
public abstract Buffer slice(int index, int length);
//復(fù)制一個(gè)buffer
public abstract Buffer duplicate();
//
abstract Object base();
構(gòu)造函數(shù)
Buffer(long addr, int cap, MemorySegmentProxy segment) {this.address = addr;
this.capacity = cap;
this.segment = segment;
}
Buffer(int mark, int pos, int lim, int cap, MemorySegmentProxy segment) { // package-private
if (cap< 0)
throw createCapacityException(cap);
this.capacity = cap;
this.segment = segment;
limit(lim);
position(pos);
if (mark >= 0) {if (mark >pos)
throw new IllegalArgumentException("mark >position: ("
+ mark + ">" + pos + ")");
this.mark = mark;
}
}
普通方法
在這里插入代碼片
字段
static final Unsafe UNSAFE = Unsafe.getUnsafe();
static final ScopedMemoryAccess SCOPED_MEMORY_ACCESS = ScopedMemoryAccess.getScopedMemoryAccess();
static final int SPLITERATOR_CHARACTERISTICS =
Spliterator.SIZED | Spliterator.SUBSIZED | Spliterator.ORDERED;
private int mark = -1;
private int position = 0;
private int limit;
private int capacity;
long address;
// Used by buffers generated by the memory access API (JEP-370)
final MemorySegmentProxy segment;
子類
常見類型的緩沖
public abstract class ByteBuffer
extends Buffer
implements Comparable{}
ByteBuffer是抽象類無法直接實(shí)例化,可以通過allocate等方法返回實(shí)例。
allocate
public static ByteBuffer allocate(int capacity) {if (capacity< 0)
throw new IllegalArgumentException();
return new HeapByteBuffer(capacity, capacity);
}
allocateDirect
public static ByteBuffer allocateDirect(int capacity) {return new DirectByteBuffer(capacity);
}
ByteBuffer 分為HeapByteBuffer和DirectByteBuffer兩種,翻譯成人話就是堆字節(jié)緩沖和直接字節(jié)緩沖,第二種不受 JVM 控制。
ByteBuffer hbb = ByteBuffer.allocate(1024);
ByteBuffer dbb = ByteBuffer.allocateDirect(1024);
在后面的介紹中,hbb代指 JVM 緩沖區(qū),dbb代指直接緩沖區(qū)。
HeapByteBuffer DirectByteBuffer 常見方法 allocate下面對(duì) allocate 的調(diào)用鏈路參數(shù)進(jìn)行分析。
public static ByteBuffer allocate(int capacity) {if (capacity< 0)
throw new IllegalArgumentException();
//capacity >= 0
return new HeapByteBuffer(capacity, capacity);
}
cap = lim = capacity,由 HeapByteBuffer 構(gòu)造函數(shù)調(diào)用 super
HeapByteBuffer(int cap, int lim) {
super(-1, 0, lim, cap, new byte[cap], 0);
}
mark = -1
pos = 0
lim = cap
cap = cap
hb = new byte[cap]
offset = 0
ByteBuffer(int mark, int pos, int lim, int cap,
byte[] hb, int offset)
{super(mark, pos, lim, cap); //-1,0,cap,cap
this.hb = hb; //new byte[cap]
this.offset = offset; //0
}
hb字節(jié)數(shù)組和offset 偏移量為 ByteBuffer 字段。
mark = -1
pos = 0
lim = cap
cap = cap
Buffer(int mark, int pos, int lim, int cap) { //判斷多余 cap >0
if (cap< 0)
throw new IllegalArgumentException("Negative capacity: " + cap);
this.capacity = cap; // 1
limit(lim); //2
position(pos); //3
//匯總分析的參數(shù) mark = -1,pos = 0
if (mark >= 0) {if (mark >pos)
throw new IllegalArgumentException("mark >position: ("
+ mark + ">" + pos + ")");
this.mark = mark;
}
}
核心代碼表示為1,2,3的部分。
public final Buffer limit(int newLimit) {// newLimit = lim = cap
if ((newLimit >capacity) || (newLimit< 0))
throw new IllegalArgumentException();
limit = newLimit; //limit = newLimit = lim = cap
if (position >limit) position = limit; // position = 0 limit = cap
if (mark >limit) mark = -1; // mark = -1
return this;
}
public final Buffer position(int newPosition) {// newPosition = pos = pos = 0
if ((newPosition >limit) || (newPosition< 0))
throw new IllegalArgumentException();
position = newPosition; // position = newPosition = pos = pos = 0
if (mark >position) mark = -1;
return this;
}
所以經(jīng)過這一串構(gòu)造函數(shù)后,buffer中的值分別為
java.nio.HeapByteBuffer[pos=0 lim=1024 cap=1024]
pos = 位置,lim = 限制,cap = 容量,大值。
allocateDirectpublic static ByteBuffer allocateDirect(int capacity) {return new DirectByteBuffer(capacity);
}
DirectByteBuffer(int cap) {//cap = capacity
//調(diào)用鏈路
super(-1, 0, cap, cap);
//
boolean pa = VM.isDirectMemoryPageAligned();
int ps = Bits.pageSize();
long size = Math.max(1L, (long)cap + (pa ? ps : 0));
Bits.reserveMemory(size, cap);
long base = 0;
try { //unsafe 分配內(nèi)存空間
base = unsafe.allocateMemory(size);
} catch (OutOfMemoryError x) {Bits.unreserveMemory(size, cap);
throw x;
}
unsafe.setMemory(base, size, (byte) 0);
if (pa && (base % ps != 0)) {// Round up to page boundary
address = base + ps - (base & (ps - 1));
} else {address = base;
}
cleaner = Cleaner.create(this, new Deallocator(base, size, cap));
att = null;
}
MappedByteBuffer(int mark, int pos, int lim, int cap) {// package-private
super(mark, pos, lim, cap);
this.fd = null;
}
ByteBuffer(int mark, int pos, int lim, int cap) {// package-private
this(mark, pos, lim, cap, null, 0);
}
ByteBuffer(int mark, int pos, int lim, int cap, // package-private
byte[] hb, int offset)
{super(mark, pos, lim, cap);
this.hb = hb;
this.offset = offset;
}
Buffer(int mark, int pos, int lim, int cap) { // package-private
if (cap< 0)
throw new IllegalArgumentException("Negative capacity: " + cap);
this.capacity = cap;
limit(lim);
position(pos);
if (mark >= 0) {if (mark >pos)
throw new IllegalArgumentException("mark >position: ("
+ mark + ">" + pos + ")");
this.mark = mark;
}
}
調(diào)用過程不再贅述,跟 allocate 鏈路差不多,區(qū)別是使用 unsafe 進(jìn)行內(nèi)存分配和其他的操作。
flip 翻轉(zhuǎn)public final Buffer flip() {limit = position;
position = 0;
mark = -1;
return this;
}
案例
ByteBuffer hbb = ByteBuffer.allocate(1024);
System.out.println(hbb.toString());
hbb.flip();
System.out.println(hbb.toString());
輸出
java.nio.HeapByteBuffer[pos=0 lim=1024 cap=1024]
java.nio.HeapByteBuffer[pos=0 lim=0 cap=1024]
hasRemaining 是否有剩余public final boolean hasRemaining() {return position< limit;
}
position< limit 代表有剩余,position = limit 代表空間已經(jīng)滿了
clear 清除public final Buffer clear() {position = 0;
limit = capacity;
mark = -1;
return this;
}
將buffer三個(gè)指針位置重置。
gethbb
final byte[] hb;
public byte get() {return hb[ix(nextGetIndex())];
}
dbb
public byte get() {return ((unsafe.getByte(ix(nextGetIndex()))));
}
asReadOnlyBuffer 只讀bufferpublic ByteBuffer asReadOnlyBuffer() {return new HeapByteBufferR(hb, this.markValue(), this.position(), this.limit(),
this.capacity(), offset);
}
buffer 案例1 基本操作讀和寫創(chuàng)建5個(gè)容量的buffer,依次將i放進(jìn)去,翻轉(zhuǎn)buf,依次讀出來。
public class byteBuffer02 {public static void main(String[] args) {ByteBuffer buffer = ByteBuffer.allocate(5);
for (byte i = 0; i< buffer.capacity(); i++) {buffer.put(i);
}
buffer.flip();
while (buffer.hasRemaining()) {System.out.println(buffer.get());
}
}
}
buffer 案例2 不同類型數(shù)據(jù)讀寫public class ByteBuffer03 {public static void main(String[] args) {ByteBuffer bb = ByteBuffer.allocate(64);
bb.putInt(100);
bb.putLong(9);
bb.putChar('a');
bb.putShort((short) 4);
bb.flip();
System.out.println("----");
System.out.println(bb.getInt());
System.out.println(bb.getLong());
System.out.println(bb.getChar());
System.out.println(bb.getShort());
}
}
buffer 案例3 只讀 bufferpublic class ByteBuffer04 {public static void main(String[] args) {ByteBuffer b1 = ByteBuffer.allocate(64);
ByteBuffer b2 = b1.asReadOnlyBuffer();
b1.putInt(5);
b2.putInt(5);
}
}
MappedByteBuffer深入淺出java.nio.MappedByteBuffer
Channel 通道實(shí)現(xiàn)
源碼
public interface Channel extends Closeable {//是否開啟
public boolean isOpen();
//關(guān)閉
public void close() throws IOException;
}
FileChannel
開啟通道的幾種方式static File file = new File("D://a.txt");
從 RandomAccessFile 中g(shù)etChannelRandomAccessFile raf = new RandomAccessFile(file, "rw");
FileChannel fc = raf.getChannel();
從 stream 中 getChannelFileOutputStream fos = new FileOutputStream(file);
FileChannel fc2 = fos.getChannel();
FileChannel.openFileChannel fc3 = FileChannel.open(null, null);
案例1將 uuid 讀出來
public class ReadFileUid {static File file = new File("D://a.txt");
public static void main(String[] args) throws Exception {ByteBuffer bf = ByteBuffer.allocate(1024);
try (RandomAccessFile raf = new RandomAccessFile(file, "rw");
FileChannel fc = raf.getChannel()) {int read = fc.read(bf);
System.out.println(read);
System.out.println(bf);
bf.flip();
System.out.println(bf);
byte[] bytes = new byte[bf.limit()];
bf.get(bytes);
System.out.println(bf);
System.out.println(Arrays.toString(bytes));
String str = new String(bytes, StandardCharsets.UTF_8);
System.out.println(str);
}
}
}
輸出
36
java.nio.HeapByteBuffer[pos=36 lim=1024 cap=1024]
java.nio.HeapByteBuffer[pos=0 lim=36 cap=1024]
java.nio.HeapByteBuffer[pos=36 lim=36 cap=1024]
[54, 51, 51, 53, 98, 102, 53, 97, 45,
99, 57, 100, 54, 45, 52, 53, 51, 99,
45, 98, 57, 99, 98, 45, 102, 50, 52,
102, 56, 97, 54, 101, 98, 50, 99, 50]
6335bf5a-c9d6-453c-b9cb-f24f8a6eb2c2
案例2將 uuid 寫到文件中
public class WriteFileUid {static File file = new File("D://a.txt");
public static void main(String[] args) throws Exception {ByteBuffer bf = ByteBuffer.allocate(1024);
try (RandomAccessFile raf = new RandomAccessFile(file, "rw");
FileChannel fc = raf.getChannel()) {String uuid = UUID.randomUUID().toString();
System.out.println(uuid);
byte[] bytes = uuid.getBytes(StandardCharsets.UTF_8);
System.out.println(Arrays.toString(bytes));
System.out.println(bf);
bf.put(bytes);
System.out.println(bf);
bf.flip();
System.out.println(bf);
int write = fc.write(bf);
System.out.println(write);
}
}
}
efdd8059-4f47-42e9-b9f9-aadd4a324309
[101, 102, 100, 100, 56, 48, 53, 57, 45, 52, 102, 52, 55,
45, 52, 50, 101, 57, 45, 98, 57, 102, 57, 45, 97, 97,
100, 100, 52, 97, 51, 50, 52, 51, 48, 57]
java.nio.HeapByteBuffer[pos=0 lim=1024 cap=1024]
java.nio.HeapByteBuffer[pos=36 lim=1024 cap=1024]
java.nio.HeapByteBuffer[pos=0 lim=36 cap=1024]
36
你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級(jí)服務(wù)器適合批量采購,新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧
網(wǎng)頁名稱:深入淺出javanio-創(chuàng)新互聯(lián)
URL鏈接:http://chinadenli.net/article12/dgpsgc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供全網(wǎng)營銷推廣、手機(jī)網(wǎng)站建設(shè)、網(wǎng)站建設(shè)、網(wǎng)站營銷、網(wǎng)站改版、網(wǎng)站策劃
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容