JDK-In-Action-NIO-ByteBuffer
ByteBuffer
ByteBuffer
用于NIO的可以在堆内存中分配或者直接内存中分配的缓冲区实现,有8中具体的类型.
ByteBuffer
具有三个核心属性:
- capacity : 缓冲区容量
- limit : 读写限制索引
- position : 读写开始索引
通过操纵 limit 和 position 两个索引,来对缓冲区进行读写,具体参见下文API示例.
API 示例
Buffer的三个重要属性
ByteBuffer buffer = ByteBuffer.allocate(8);
//初始属性
assertEquals(buffer.capacity(), 8);
assertEquals(buffer.limit(), 8);
assertEquals(buffer.position(), 0);
//写入数据后属性
buffer.putInt(10);
assertEquals(buffer.capacity(), 8);
assertEquals(buffer.limit(), 8);
assertEquals(buffer.position(), 4);
//翻转为读模式
buffer.flip();
assertEquals(buffer.capacity(), 8);
assertEquals(buffer.limit(), 4);
assertEquals(buffer.position(), 0);
//读数据后属性
buffer.getInt();
assertEquals(buffer.capacity(), 8);
assertEquals(buffer.limit(), 4);
assertEquals(buffer.position(), 4);
//清空数据后属性
buffer.clear();
assertEquals(buffer.capacity(), 8);
assertEquals(buffer.limit(), 8);
assertEquals(buffer.position(), 0);
Buffer管理之 Clear与 Compact
ByteBuffer buffer = ByteBuffer.allocate(12);
buffer.putInt(8);
//重置索引值,不会直接操作数据
buffer.clear();
assertEquals(buffer.capacity(), 12);
assertEquals(buffer.limit(), 12);
assertEquals(buffer.position(), 0);
buffer.putInt(8);
buffer.flip();
int i = buffer.getInt();
assertEquals(i, 8);
//丢弃已读数据,拷贝buffer覆盖已读数据
buffer.compact();
assertEquals(buffer.capacity(), 12);
assertEquals(buffer.limit(), 12);
assertEquals(buffer.position(), 0);
buffer.putInt(8);
Buffer管理之 Mark与 Reset
ByteBuffer buffer = ByteBuffer.allocate(12);
buffer.putInt(8);
buffer.putInt(9);
//标记position位置
buffer.mark();
buffer.putInt(10);
//还原position位置
buffer.reset();
//读position之后的数据
int i = buffer.getInt();
assertEquals(i, 10);
Buffer重复 Rewind
CharBuffer buffer = CharBuffer.wrap(new char[]{'1', '2', '3'});
char c = buffer.get();
assertEquals(c, '1');
c = buffer.get();
assertEquals(c, '2');
buffer.rewind();
char cc = buffer.get();
assertEquals(cc, '1');
Jdk Nio分开读 Scatter与聚合写 Gather
try {
File tempFile = File.createTempFile("test", ".txt");
FileChannel channel = FileChannel.open(tempFile.toPath(), StandardOpenOption.WRITE);
ByteBuffer header = ByteBuffer.wrap("Header".getBytes());
ByteBuffer body = ByteBuffer.wrap("Body".getBytes());
//Gather
channel.write(new ByteBuffer[]{header, body});
channel.close();
channel = FileChannel.open(tempFile.toPath(), StandardOpenOption.READ);
ByteBuffer h = ByteBuffer.allocate(header.capacity());
ByteBuffer b = ByteBuffer.allocate(body.capacity());
//Scatter
channel.read(new ByteBuffer[]{h, b});
channel.close();
assertEquals(header, h);
assertEquals(body, b);
} catch (IOException e) {
e.printStackTrace();
}
NIO的8种 Buffer类型
ByteBuffer byteBuffer = ByteBuffer.allocate(1);
ByteBuffer buffer = MappedByteBuffer.allocateDirect(1);
CharBuffer charBuffer = CharBuffer.wrap(new char[]{1});
ShortBuffer shortBuffer = ShortBuffer.allocate(2);
IntBuffer intBuffer = IntBuffer.wrap(new int[]{1});
LongBuffer longBuffer = LongBuffer.allocate(8);
FloatBuffer floatBuffer = FloatBuffer.allocate(4);
DoubleBuffer doubleBuffer = DoubleBuffer.allocate(8);
分配堆内存缓冲区
ByteBuffer buffer = ByteBuffer.allocate(4);
assertEquals(buffer.isDirect(), false);
分配直接内存缓冲区
ByteBuffer buffer = ByteBuffer.allocateDirect(4);
assertEquals(buffer.isDirect(), true);
缓冲区读写基本步骤
ByteBuffer buffer = ByteBuffer.allocate(4);
//写入数据
buffer.putInt(10);
//翻转
buffer.flip();
//读数据
int v = buffer.getInt();
//清理
buffer.clear();
assertEquals(v, 10);
读文件数据到 Buffer
try {
File resource = new File(SRC_ROOT_DIR, ByteBufferExample.class.getCanonicalName().replaceAll("\\.", "/") + ".java");
FileChannel fileChannel = FileChannel.open(resource.toPath(), StandardOpenOption.READ);
ByteBuffer buffer = ByteBuffer.allocate(128);
fileChannel.read(buffer);
fileChannel.close();
System.out.println(new String(buffer.array()));
buffer.clear();
} catch (IOException e) {
e.printStackTrace();
}
package com.gitee.zhwcong.nio;
import com.gitee.zhwcong.Example;
import javax.print.DocFlavor;
import java.io.File;
impo
引用
- 源码下载
java.nio.ByteBuffer
Source Code