Buffer 主要用于和 NIO 中的通道进行交互。数据是从通道读入缓冲区,从缓冲区写入到通道中。
缓冲区本质上是一块可以写入数据,然后可以从中读取数据的内存。这块内存被包装成了NIO Buffer对象,并提供了一组方法,用来方便的访问该块内存。
1、Buffer的基本用法
使用Buffer读写数据一般遵循一下四哥步骤:
写入数据到Buffer
调用 flip( )方法
从Buffer中读取数据
调用 clear( )方法或者 compact( )方法
当向buffer写入数据时,buffer会记录下谢了多少数据。一旦要读取数据,需要通过 filp( )方法将Buffer从写模式切换到读模式,可以读取之前写入到buffer的所有数据。
一旦读完了所有的数据,就需要清空缓冲区,让它可以再次被写入。有两种方式能清空缓冲区:调用 clear( ) 或 compact()方法。clear()方法会清空整个缓冲区。compact()方法只会清楚已经读过的数据。任何未读的数据都会被移到缓冲区的起始处,新写入数据将放到缓冲区未读数据的后面。
package nio;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class channel {
void cha() throws IOException {
RandomAccessFile aFile = new RandomAccessFile("d:/date/nio.txt", "rw");
FileChannel inChannel = aFile.getChannel();
// 创立一个capacity为48的buffer
ByteBuffer buf = ByteBuffer.allocate(48);
// 将数据读到buffer内
int bytesRead = inChannel.read(buf);
while (bytesRead != -1) {
System.out.println("Read " + bytesRead);
// 调用filp方法切换到读模式
buf.flip();
while (buf.hasRemaining()) {
// 读取buffer的内容
System.out.print((char) buf.get());
}
// 清除buffer的内容,让后面的内容读进来
buf.clear();
bytesRead = inChannel.read(buf);
}
aFile.close();
}
public static void main(String[] args) {
channel s = new channel();
try {
s.cha();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
2、Buffer的capacity,position和limit
缓冲区本质是内存,为了理解Buffer的工作原理,需要熟悉它的三个属性:
capacity
position
limit
position和limit的含义取决于Buffer处在读模式还是写模式,不管Buffer处在什么模式,capacity的含义总是一样的。
capacity
作为内存块,Buffer有一个固定的大小值,叫做 capacity
position
写数据到Buffer中时,position表示当前的位置。初始的position值为0.当一个数据写到Buffer后,position会向前移动到下一个可插入数据的Buffer单元。
读模式时,也是从某个特定位置读。当将Buffer从写模式切换到读模式,position会被重置为0.
limit
在写模式下,Buffer的limit表示你最多能往Buffer里写多少数据。写模式下,limit等于capacity
在读模式下,limit表示你能从Buffer中读到多少数据。
Buffer的类型
ByteBuffer
MappedByteBuffer
CharBuffer
DoubleBuffer
FloatBuffer
IntBuffer
LongBuffer
ShortBuffer
Buffer的分配
想要获得一个Buffer对象,首先要进行分配。每一个Buffer类都有一个allocate方法。参数为字节。
ByteBuffer buf = ByteBuffer.allocate(48);
向Buffer中写数据
写数据有两种方式:
1、从Channle写到Buffer。
2、通过Buffer的put()方法写到Buffer里
1、int bytesRead = inChannel.read(buf);//read into buffer
2、buf.put(127);
filp( )方法
filp方法将Buffer从写模式切换到读模式。
从Buffer中读取数据
有两种方式:
1、从Buffer读取数据到Channel。
2、使用get( )方法从Buffer中读取数据。
1、 int bytesWritten = inChannel.write(buf);//read from buffer into channel
2、 byte aByte = buf.get();
rewind( )方法
可以将position设回0,重读buffer中的数据。limit保持不变。
clear( ) 与 compact( ) 方法
读完了Buffer中的数据,需要让Buffer准备好再次被写入。可以通过此方法完成。
clear() 清除buffer中的数据。
compact( ) 清除已读数据,将未读数据拷贝到Buffer起始处,将position设到最后一个未读元素后。
mark( ) 与 reset( ) 方法
mark标记Buffer中的一个特定position。之后可以通过reset恢复到这个position。