NIO基本概念

时间:2022-06-11 06:11:02
1.  IO和NIO的区别
 IO     面向流(stream oriented)  阻塞(blocking io) 无  
                NIO  面向缓冲区(buffer oriented)非阻塞(Non blocking io)选择器(selectors)
Java NIO的系统核心在于:通道(Channel)和缓冲区(Buffer)。通道表示打开到IO设备(例如文件、套接字)的连接。若需要使用NIO
系统,需要获取用于连接IO设备的通道和用于容纳数据的缓冲区。然后操作缓冲区,对数据进行处理。
简言之:Channel负责传输,Buffer负责存储
2.缓冲区的数据存取
 底层数据  根据数据类型的不同(boolean) 提供对应类型的缓冲区
 ByteBuffer
 CharBuffer
 ShortBuffer
 IntBuffer
 LongBuffer
 FloatBuffer
 DoubleBuffer
 
 ByteBuffer buf = new ByteBuffer,allocate(1024);
 缓冲区的核心方法:put()存数据     get()取出数据
 缓冲区的四个核心属性:capacity容量    limit界限   position位置  mark标记(reset()方法恢复position的位置)
 0 <=mark<=position<=limit<=capacity
 flip()切换到读取数据的模式 
 rewind()可重复读数据
 clear()清空缓冲区 数据依然存在,但是处于“被遗忘”状态
3.直接缓冲区和非直接缓冲区
 直接缓冲区:通过allocate()分配,将缓冲区建立在JVm内存中
 非直接缓冲区:通过allocateDirect()分配,将缓冲区建立在物理内存中,可以提高效率
 isDirect()判断是否是直接缓冲区
 
4非直接缓冲区进行文件复制
package com.hpd.nio;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel; import org.junit.jupiter.api.Test; public class TestChannel {
//非直接缓冲区进行文件复制
@Test
public void test1() {
FileInputStream fin = null;
FileOutputStream fos = null;
// 获取通道
FileChannel inChannel = null;
FileChannel outChannel = null;
try {
fin = new FileInputStream("1.png");
fos = new FileOutputStream("2.png"); inChannel = fin.getChannel();
outChannel = fos.getChannel(); // 分配指定大小的缓冲区
ByteBuffer buffer = ByteBuffer.allocate(); // 将通道中的数据写入缓冲区
while ((inChannel.read(buffer)) != -) {
buffer.flip(); // 切换成读模式
// 将缓冲区中的数据写入通道
outChannel.write(buffer);
buffer.clear(); // 清空缓冲区
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (outChannel != null) {
try {
outChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (inChannel != null) {
try {
inChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fin != null) {
try {
fin.close();
} catch (IOException e) {
e.printStackTrace();
}
} } } }

5.直接缓冲区进行文件复制

//直接缓冲区进行文件的复制(内存映射文件)
@Test
public void test2() throws IOException {
FileChannel inChannel = FileChannel.open(Paths.get("1.png"), StandardOpenOption.READ);
FileChannel outChannel = FileChannel.open(Paths.get("3.png"),StandardOpenOption.READ,StandardOpenOption.WRITE,StandardOpenOption.CREATE); //内存映射文件
MappedByteBuffer inMapBuffer = inChannel.map(MapMode.READ_ONLY, 0, inChannel.size());
MappedByteBuffer outMapBuffer = outChannel.map(MapMode.READ_WRITE, 0, inChannel.size()); //直接对缓冲区进行数据的读写操作
byte[] dst = new byte[inMapBuffer.limit()];
inMapBuffer.get(dst);
outMapBuffer.put(dst); inChannel.close();
outChannel.close();
}