nio的学习

java中nio的核心是通道和缓冲区,它与IO的区别是面 向缓冲区,非阻塞IO,有选择器。

缓冲区负责数据存取,缓冲区就是数组。根据数据类型不同(boolean除外),提供相应类型缓冲区。

缓冲区四个核心属性:

capacity:容量,表示缓冲区中最大存储数据人的容量,一旦声明不能改变。

limit:界限,缓冲区中可以操作数据的大小

position:位置,表示缓冲区中正在操作数据的位置

mark:标记,记录当前positon位置,可以通过reset()恢复到mark位置。

分配缓冲区大小:allocate(num)

ByteBuffer buf = ByteBuffer.allocate(1024);//分配大小

存入缓冲区数据put()

buf.put("abc".getBytes());

获取缓冲区数据get()

buf.flip();//切换到读模式positon和limit会改变为缓冲区大小
but.get(byte[]);

重复读数据rewind();

清空缓冲区clear();

直接缓冲区:通过allocateDirect()方法直接在主内存中建立缓冲区。

非直接缓冲区:通过allocate()方法分配缓冲区,将缓冲区建立在jvm的内存中

通道:用于源与目标节点的连接,负责缓冲区中数据的传输。

通道有FileChannel、SocketChannel、等,getChannel()方法获取通道。针对通道提供了open(),

非直接缓冲区复制文件

FileInputStream fis = new FileInputStream("a.jpg");
FileOutStream fos = new FileOutputStream("b.jpg");

//获取通道
FileChannel inChannel = fis.getChannel();
FileChannel outChannel = fos.getChannel();

//分配缓冲区大小
ByteBuffer buf = ByteBuffer.allocate(1024);

//将通道中的数据写入缓冲区
while(inChannel.read(buf)!=-1){
    buf.flip();//切换读取模式
    outChannel.write(buf);//将缓冲区中的数据写入通道
    buf.clear();//清空缓冲区
}


outChannel.close();
inChannel.close();
fis.close();
fos.close();

直接缓冲区文件复制

FileChannel in = FileChannel.open(Paths.get("a.jpg"),StandardOpenOption.READ);
FileChannel out = FileChannel.open(Paths.get("b.jpg"),StandardOpenOption.WRITE,StandardOpenOption.READ,StandardOpenOption.CREATE_NEW);
//内存映射文件
MappedByteBuffer inMappedBuf = in.map(MapMode.READ_ONLY,0,in.size());
MappedByteBuffer outMappedBuf = out.map(MapMode.READ_WRITE,0,in.size());
//直接对缓冲区进行数据的读写操作
byte[] dst = new byte[inMappedBuf.limit()];
inMappedBuf.get(dst);
outMappedBuf.put(dst);

in.close();
out.close();

通道间的数据传输

FileChannel in = FileChannel.open(Paths.get("a.jpg"),StandardOpenOption.READ);
FileChannel out = FileChannel.open(Paths.get("b.jpg"),StandardOpenOption.WRITE,StandardOpenOption.READ,StandardOpenOption.CREATE_NEW);

in.transferTo(0,in.size(),out);
//out
.transferFrom(0,in.size(),in);
in.close(); out.close();

Scatter(分散):将通道中的数据分散到多Buffer中去。

RandomAccessFile raf1 = new RandomAccessFile("1.txt","rw");

//获取通道
FileChannel channel1 =raf1.getChannel();

//分配指定大小缓冲区
ByteBuffer buf1 = ByteBuffer.allocate(100);
ByteBuffer buf2 = ByteBuffer.allocate(1024);

//分散读取
ByteBuffer[] bufs = {buf1,buf2};
channel1.read(bufs);

for(ByteBuffer byteBuffer:bufs){
    byteBuffer.flip();
}

//聚集写入
RandomAccessFile raf2 = new RandomAccessFile("2.txt","rw");
//获取通道
FileChannel channel2 =raf2.getChannel();

channel2.write(bufs);

编码:

Charset.availableCharsets();

Charset cs = Charset.forName("GBK");
//获取编码器
CharsetEncoder ce = cs1.newEncoder();
//获取解码器
CharsetDecoder cd = cs1.newDecoder();
 
CharBuffer cBuf = CharBuffer.allocate(1024);
cBuf.put("这是测试");
cBuf.flip();

//编码
ByteBuffer bBuf  =ce.encode(cBuf);

//解码
bBuf.flip();
CharBuffer cBuf2 = cd.decode(dBuf);

Gather(聚集):

猜你喜欢

转载自www.cnblogs.com/javage/p/9501357.html