Buffer用于和NIO通道进行交互,数据从通道读入缓冲区,从缓冲区写入通道,缓冲区本质上就是一块可以写入数据,然后从中读取数据的内存,在NIO库中,所有的数据都是用缓冲区处理的
Buffer的基本使用方法
读写数据:
- 写入数据到buffer
- 调用flip反转读写模式
- 从buffer中读取数据
- 调用clear(清除所有的数据)方法或者compact方法(只会清除已经读过的数据,新写入的数据会放在未读数据的后面)清除buffer
读入文件数据并且打印的代码:
public void testWriteRead() throws IOException {
//打开一个Channel
RandomAccessFile accessFile = new RandomAccessFile("E:\\testData\\FileChannel01.txt", "rw");
FileChannel channel = accessFile.getChannel();
//创建buffer
ByteBuffer buffer = ByteBuffer.allocate(1024);
//读取buffer
while (channel.read(buffer)!=1){
//转换到读模式
buffer.flip();
while (buffer.hasRemaining()){
System.out.println((char) buffer.get());
}
buffer.clear();
}
accessFile.close();
}
IntBuffer的使用
@Test
public void testWriteRead2() throws IOException {
//创建一个intBuffer
IntBuffer buffer=IntBuffer.allocate(8);
//向buffer里添加数据
for (int i = 0; i < buffer.capacity(); i++) {
buffer.put(i);
}
//重置缓冲区
buffer.flip();
//获取
while (buffer.hasRemaining()){
System.out.println(buffer.get());
}
}
Buffer的capacity,position和limit和一些方法
capacity:
作为一个内存块,buffer有一个固定大小的值,你只能往里面写capacity个byte,long,char等类型,一但buffer满了,就需要将其清空才能继续往里面写数据
position:
写数据到buffer时,position表示写入数据的当前位置,position的初始值为0,当一个数据写到buffer后,position会向下移动到下一个可以插入数据的buffer单元,position最大可以为capacity-1
读数据到buffer中时,position表示读入数据的当前位置,当调用flip的时候position会被重置为0,也就是从最开始写入的数据位置开始读
limit:
写数据的时候: limit表示可以对buffer最多写入多少个数据,等于capacity
读数据的时候:limit表示Buffer有多少可以读的数据,因此能读到之前所有写入的数据,limit被设置成已写数据的数量,这个值在写模式下就是position
向Buffer中读写数据:
从Channel写到buffer: int read=channel.read(buf);
直接写入:buffer.put
从buffer中读数据到channel:int write=channel.write(buf)
直接读取:buf.get
rewind方法
将position设置为0,所以可以重写读buffer中的所有数据,limit保持不变,仍然可以表示buffer中读取多少个元素
mark方法和reset方法
通过调用mark可以标记buffer中一个特定的position,之后可以通过调用reset来恢复到这个position
缓冲区分片
@Test
public void b01(){
ByteBuffer buffer=ByteBuffer.allocate(10);
for (int i = 0; i < buffer.capacity(); i++) {
buffer.put((byte)i);
}
//创建一个子缓冲区
buffer.position(3);
buffer.limit(7);
ByteBuffer slice = buffer.slice();
//改变子缓冲区的内容
for (int i = 0; i < slice.capacity(); i++) {
byte b = slice.get();
b*=10;
slice.put(i,b);
}
buffer.position(0);
buffer.limit(buffer.capacity());
//读取
while (buffer.hasRemaining()){
System.out.println(buffer.get());
}
}
输出效果:
0
1
2
30
40
50
60
7
8
9
只读缓冲区和直接缓冲区
通过asReadOnlyBuffer创建一个只读缓冲区
通过allocateDirect方法创建一个直接缓冲区,使用方式和普通的并无区别,该缓冲区是为了加快IO速度,给定一个直接字节缓冲区,java虚拟机将尽最大努力对他执行本机的IO操作
内存映射文件IO