- 标准I/O是基于流实现以字节为单位处理数据的(InputStream/OutputStream)
- NIO是基于块实现的,以块为基本单位处理数据。
- 为所有原始类型提供buffer缓存支持
- 增加通道对象(Channel),作为新的原始I/O抽象
- 提供基于Selector的异步网络I/O
-
2.1 NIO中最重要的两个组件是缓存Buffer和通道Channel。 - Buffer和Channel的配合使用:
package nio;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class NIO {
public static void main(String[] args) {
String resource = "E:/aaa.txt";
String destination = "F:/aa.txt";
try {
nioCopyFile(resource, destination);
} catch (Exception e) {
e.printStackTrace();
}
}
@SuppressWarnings("resource")
public static void nioCopyFile(String resource, String destination) throws Exception {
FileInputStream fis = new FileInputStream(resource);
FileOutputStream fos = new FileOutputStream(destination);
FileChannel readChannerl = fis.getChannel();
FileChannel writeChannerl = fos.getChannel();
// 缓存
ByteBuffer buffer = ByteBuffer.allocate(1024);
while (true) {
buffer.clear();
// 读入数据
int len = readChannerl.read(buffer);
if (len == -1) {
break;
}
// flip()使缓冲区为一系列新的通道写入或相对获取 操作做好准备:它将限制设置为当前位置,然后将位置设置为0。limit的值设为position的当前值,再将position的值设为0。
buffer.flip();
// 写入数据
writeChannerl.write(buffer);
}
readChannerl.close();
writeChannerl.close();
}
}
- Buffer的基本原理
- 3个重要的参数:
- 位置(position):当前位置
- 容量(capacity):缓冲区总容量上限
- 上限(limit):缓冲区实际容量上限,小于等于容量
- 理解 flip():关键在于上次读取的范围,limit被重新定位,用于防止读取越界。读写切换时调用
- 3个重要的参数:
3.1 Buffer的相关创建
// 方法1:从堆中分配
ByteBuffer buffer = ByteBuffer.allocate(1024);
// 方法2:从既有数组中创建
byte array[] = new byte[1024];
ByteBuffer buffer1 = ByteBuffer.wrap(array);
3.2 Buffer的重置
- rewind():读取buffer中有效数据做准备
- clear():未重新写入buffer做准备
- flip():在读写切换时调用
-
3.3 读/写缓冲区
- get():position位置后移一位
- get(byte[] dst)
- get(int index)
- put(byte b):position位置后移一位
- put(int index, byte b)
- put(byte[] src)
-
3.4 标志缓冲区
- public final Buffer mark():记录当前位置
- public final Buffer reset():恢复到mark所在的位置