1、Buffer的基础用法
package com.fyd.nio;
import java.nio.IntBuffer;
/***
* @Author付亚东
* @Date 2020/5/26 22:00
****/
public class BasicBuffer {
public static void main(String[] args) {
//buffer简单说明
//创建一个buffer,可以存放5个int
IntBuffer intBuffer = IntBuffer.allocate(5);
//向buffer中存放数据
intBuffer.put(10);
intBuffer.put(11);
intBuffer.put(12);
intBuffer.put(13);
intBuffer.put(14);
//向buffer中取数据
//将buffer切换状态,读写切换
intBuffer.flip();
while (intBuffer.hasRemaining()){
System.out.println(intBuffer.get());
}
}
}
2、Buffer只读模式
package com.fyd.nio;
import java.nio.ByteBuffer;
/***
* @Author付亚东
* @Date 2020/5/31 17:22
****/
public class ReadOnlyBuffer {
public static void main(String[] args) {
ByteBuffer byteBuffer = ByteBuffer.allocate(64);
for (int i=0;i<64;i++){
byteBuffer.put((byte) i);
}
byteBuffer.flip();
//只读的buffer
ByteBuffer reasOnlyBuffer = byteBuffer.asReadOnlyBuffer();
System.out.println(reasOnlyBuffer.getClass());
while (reasOnlyBuffer.hasRemaining()){
System.out.println(reasOnlyBuffer.get());
}
//不能put
}
}
3、Buffer的put和get有顺序,并且类型要一致
package com.fyd.nio;
import java.nio.ByteBuffer;
/***
* @Author付亚东
* @Date 2020/5/31 17:18
****/
public class NIOByteBufferPutGet {
public static void main(String[] args) {
ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
byteBuffer.putInt(100);
byteBuffer.putChar('你');
byteBuffer.putLong(2);
byteBuffer.putShort((short) 3);
byteBuffer.flip();
System.out.println(byteBuffer.getInt());
System.out.println(byteBuffer.getChar());
System.out.println(byteBuffer.getLong());
System.out.println(byteBuffer.getShort());
}
}
4、MappedByteBuffer可以让文件直接在内存(堆外内存)做修改
package com.fyd.nio;
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
/***
* @Author付亚东
* @Date 2020/5/31 17:26
* 1、MappedByteBuffer可以让文件直接在内存(堆外内存)做修改,操作系统并不需要拷贝一次
* 2、
****/
public class MapperdByteBufferTest {
public static void main(String[] args) throws Exception{
//MappedByteBuffer mappedByteBuffer =
RandomAccessFile randomAccessFile = new RandomAccessFile("d:\\test.txt","rw");
FileChannel fileChannel = randomAccessFile.getChannel();
/**
* 参数1:FileChannel.MapMode.READ_WRITE 使用读写模式
* 参数2:0 可以修改的起始位置
* 参数3:5 映射到内存的大小(不是索引位置),即将 test.txt的多少个字节映射到内存
* 可以直接修改的范围就是0-5
*/
MappedByteBuffer map = fileChannel.map(FileChannel.MapMode.READ_WRITE, 0, 5);
map.put(0,(byte)'H');
map.put(2,(byte)'L');
randomAccessFile.close();
fileChannel.close();
}
}
5、Buffer的分散和聚合
package com.fyd.nio;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Arrays;
/***
* @Author付亚东
* @Date 2020/5/31 19:49
* Scattering:将数据写入到buffer时,可以采用buffer数组,依次写入【分散】
* Gathering:从buffer读取数据时,也可以采用buffer数组,依次读 【聚合】
****/
public class NIOScatteringAndGathering {
public static void main(String[] args)throws Exception {
//使用serversocketchannel
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
InetSocketAddress inetSocketAddress = new InetSocketAddress(7777);
//绑定端口到socket 启动
serverSocketChannel.bind(inetSocketAddress);
//创建buffer数组
ByteBuffer[] byteBuffers = new ByteBuffer[2];
byteBuffers[0] = ByteBuffer.allocate(5);
byteBuffers[1] = ByteBuffer.allocate(3);
//等待客户端链接
SocketChannel socketChannel = serverSocketChannel.accept();
int messageLength = 8;//假定从客户端接收8个字节
while (true){
int byteRead = 0;
while (byteRead<messageLength){
socketChannel.read(byteBuffers);
byteRead+=1;//累计读取的字节数
System.out.println("byteRead"+byteRead);
//使用流打印。看看当前buffer 的position和limit
Arrays.asList(byteBuffers).stream().map(byteBuffer -> "position"+byteBuffer.position()+
"limit"+byteBuffer.limit());
}
//将所有的buffer进行反转
Arrays.asList(byteBuffers).stream().map(byteBuffer -> byteBuffer.flip());
//将数据读出显示到客户端
long byteWrite = 0;
while (byteWrite<messageLength){
long l = socketChannel.write(byteBuffers);
byteWrite+=1;
}
//将所有的buffer进行clean
Arrays.asList(byteBuffers).stream().map(byteBuffer -> byteBuffer.clear());
System.out.println("byteRead="+byteRead+"byteWrite="+byteWrite);
}
}
}
我的笔记博客版权
我的笔记博客版权