1、buffer类型化和只读
buffer可以设置为已读
public static void main(String[] args) throws Exception {
ByteBuffer byteBuffer=ByteBuffer.allocate(10);
for(int i=0;i<5;i++){
byteBuffer.put((byte) i);
}
byteBuffer.flip();
//得到一个只读的buffer
ByteBuffer readBuffer=byteBuffer.asReadOnlyBuffer();
while (readBuffer.hasRemaining()){
System.out.println(readBuffer.get());
}
//此时如果put数据就会报错
}
buffer中放入是什么类型,就取出什么类型,否则会抛异常,并且取出的顺序需要和放入的顺序相同,否则会进行强制装换,例子如下:
正确代码:
public static void main(String[] args) {
ByteBuffer byteBuffer=ByteBuffer.allocate(10);
byteBuffer.putChar('d');
byteBuffer.putInt(2);
byteBuffer.putShort((short) 1);
byteBuffer.flip();
System.out.println(byteBuffer.getChar());
System.out.println(byteBuffer.getInt());
System.out.println(byteBuffer.getShort());
}
2、mappedByteBuffer
可以让文件直接在内存(堆外内存)修改,操作系统不需要拷贝一次
public static void main(String[] args) throws Exception {
RandomAccessFile randomAccessFile=new RandomAccessFile("1.txt","rw");
//获取对应通道
FileChannel fileChannel=randomAccessFile.getChannel();
/**
* 参数一:指明针对filechannel是读写模式
* 参数二:可以修改的起始位置
* 参数三:映射到内存中的大小,即将1.TXT中多少个细节映射到内存
* 即可以修改的范围时0-5
*map 的实际类型是DirectByteBuffer
*/
MappedByteBuffer map = fileChannel.map(FileChannel.MapMode.READ_WRITE, 0, 5);
map.put(0,(byte) 'b');
map.put(3,(byte) 'M');
//关闭file
randomAccessFile.close();
}
3、buffer的聚集和分散
Scatting:将数据写入buffer时,可以采用Buffer数组的模式,依次写入【分散】(即在写入的时候当一个buffer满时,写入另一个buffer)
Gathering:将数据从buffer读出数据时,也可以采用数组模式,依次读
public static void main(String[] args) throws IOException {
//使用socketcahnnel
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
InetSocketAddress inetSocketAddress = new InetSocketAddress(7000);
//绑定端口到socket
serverSocketChannel.bind(inetSocketAddress);
//创建buffer数组
ByteBuffer[] byteBuffers = new ByteBuffer[2];
byteBuffers[0]=ByteBuffer.allocate(5);
byteBuffers[1]=ByteBuffer.allocate(3);
//等待客户端的连接(telnet)
SocketChannel accept = serverSocketChannel.accept();
//设置读取的最大值
int messagelength=8;
//循环读取
while (true){
int byteread=0;
while (byteread<messagelength){
long read = accept.read(byteBuffers);
byteread+=read;//累计读取的字节数
System.out.println("byteread:"+byteread);
//使用流打印
Arrays.stream(byteBuffers).map(buffer -> "position="+buffer.position()
+","+"limit="+buffer.limit()).forEach(System.out::println);
//将所有的buffer进行翻转
Arrays.asList(byteBuffers).forEach(Buffer::flip);
//将数据读出显示到客户端
long bytewrite=0;
while (bytewrite<byteBuffers[0].capacity()+byteBuffers[0].capacity()){//当客户端发送的数据不足8位时,就会一直在此循环
long write = accept.write(byteBuffers);
bytewrite+=write;
}
//将所有的buffer进行复位操作!!!
Arrays.asList(byteBuffers).forEach(Buffer::clear);
System.out.println("byteread="+byteread+",bytewrite="+bytewrite+",messagelength="+messagelength);
}
}
}