NIO 区别于 IO, 是同步非阻塞的 nio 直接使用 native 函数库, 直接分配对外内存, 通过 DirectByteBuffer 对象作为这块内存的引用操作, 避免了数据在 java 堆和对外内存间来回复制
主要组件:
Channel 通道, 文件数据首先存在于 channel 中 可通过 FileInputStream.getChannel() 获取到 channel
Buffer 缓冲区, 数据可以从通道读入缓冲区, 也可以将数据从缓冲区写到通道中
Select 用于管理一个或多个通道
nio 读取文件示例
- public class TestChannel {
- public static void main(String[] args) throws IOException {
- // 读取到文件
- RandomAccessFile f = new RandomAccessFile("C:\\test-nio.txt", "rw");
- // 获取 channel
- FileChannel channel = f.getChannel();
- // 分配缓存大小
- ByteBuffer buffer = ByteBuffer.allocate(1024);
- // 从 channel 中读取数据循环读取到缓存中
- int bytesRead = channel.read(buffer);
- while (bytesRead != -1) {
- System.out.println("before flip:" + buffer);
- // 切换为读模式, 反转 pos 为 0, 使下一步 get 从 0 开始
- buffer.flip();
- System.out.println("after flip:" + buffer);
- while (buffer.hasRemaining()) {
- System.out.print((char) buffer.get());
- }
- // 上一步打印完成后清除缓存内数据, 使缓冲区可以再次被写入
- buffer.clear();
- System.out.println("\nafter clear:" + buffer);
- bytesRead = channel.read(buffer);
- }
- // 关闭通道
- channel.close();
- 29
- }
- }
几个方法说明:
flip() 将 buffer 从写模式切换为读模式, 是 pos=0 limit = 写模式时最后的 poslimit 表示此缓冲区中最多可以读取的字节数
clear() 清空缓冲区, 使 pos=0 limit=capaticy
compact() 将所有未读的数据拷贝到 Buffer 起始处然后将 position 设到最后一个未读元素正后面注意和 clear 区分, clear 不处理未读数据, 直接清空
rewind() 将 position 设回 0, 所以你可以重读 Buffer 中的所有数据 limit 保持不变, 仍然表示能从 Buffer 中读取多少
mark()/reset() 通过调用 Buffer.mark() 方法, 可以标记 Buffer 中的一个特定 position 之后可以通过调用 Buffer.reset() 方法恢复到这个 position
scatter 和 gather: 分散和聚合
- public class TestScatterGather {
- public static void main(String[] args) throws IOException {
- RandomAccessFile raf = new RandomAccessFile("c:/test-nio.txt", "rw");
- FileChannel channel = raf.getChannel();
- ByteBuffer header = ByteBuffer.allocate(10);
- ByteBuffer body = ByteBuffer.allocate(200);
- ByteBuffer[] bufferArr = {header,body};
- long x = channel.read(bufferArr);
- header.flip();
- while (header.hasRemaining()){
- System.out.print((char)header.get());
- }
- header.clear();
- System.out.println("============");
- body.flip();
- while (body.hasRemaining()){
- System.out.print((char)body.get());
- }
- body.clear();
- }
- }
来源: http://www.bubuko.com/infodetail-2504502.html