002 NIO 的介绍

JDK1.4出的
BIO 比较 NIO
1,是流的方式,块的方式。
2,阻塞,非阻塞
3,基于字节流或者是字符流,基于Channel和Buffer 管道和缓冲区。selector 是基于事件的监听。

在这里插入图片描述

每个channel和buffer是对应的

selector根据事件,切换到不同的channel中,所以channel会注册到selector中,event 也是事先定义好的。
所有数据的读写都是需要通过bufffer的,提高效率。
BIO中只能是一种流,而NIO是双向的。

Buffer的基本使用

package bio;

import java.nio.IntBuffer;

public class MyBuffer {
    public static void main(String[] args) {
        IntBuffer allocate = IntBuffer.allocate(1024);
        for (int i = 0; i < allocate.capacity(); i++) {
            allocate.put(i * 3);
        }

        allocate.flip();//读写的状态切花你,就是一个开关。

        while (allocate.hasRemaining()) {
            System.out.println(allocate.get());
        }
    }
}

在这里插入图片描述

Buffer其实底层就是一个封装了的数组。

在这里插入图片描述

直接子类就是没有Boolean类型的

属性
capacity 其实就是数组的大小
limit 存储数据的位置,为了读写切换
position 当前的 下一个位置 因为position是一直变化的,但是limit主要是在切换的时候变化一次
从0 开始,如果读一次,就自动+1

初始化的样子
在这里插入图片描述

    public final Buffer flip() {
        limit = position;
        position = 0;
        mark = -1;
        return this;
    }

  allocate.position(1);/设置其实位置
        allocate.limit(2);//下标不会取到limit的值

常用API后序补充

Channel

1,类似于BIO的流
2,可以同时又读和写的功能,流只能是一个功能
3,可以实现异步读写数据
4,可以从buffer中读,也可以向buffer中写。

5,Channel是一个接口:

package bio;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

public class MyChannel {
    public static void main(String[] args) throws Exception {
        String str = "hello netty";
        FileOutputStream out = new FileOutputStream("d:/a.txt");
        FileChannel channel = out.getChannel();
        ByteBuffer buffer = ByteBuffer.allocate(1024);

        buffer.put(str.getBytes());
        buffer.flip();
        channel.write(buffer);//写入文件
        out.close();



    }
}

先要对缓冲区写入
这个类是写入文件,其实一个流只做写入

package bio;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

public class MyChannel02 {
    public static void main(String[] args) throws Exception {
        File file = new File("d:/a.txt");
        FileInputStream inputStream = new FileInputStream(file);
        FileChannel channel = inputStream.getChannel();
        ByteBuffer buffer = ByteBuffer.allocate((int)file.length());
        channel.read(buffer);//读取文件
        System.out.println(new String(buffer.array()));
        inputStream.close();


    }
}

这个流只做读取。直接读取就行了

文件复制
package bio;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

public class MyChannel03 {
    public static void main(String[] args) throws Exception {
        FileInputStream in = new FileInputStream("1.txt");
        FileChannel inChannel = in.getChannel();
        FileOutputStream out = new FileOutputStream("2.txt");
        FileChannel outChannel = out.getChannel();
        ByteBuffer buffer = ByteBuffer.allocate(512);


        while (true) {
            int num = inChannel.read(buffer);
            if (num == -1) {
                break;
            }
            buffer.flip();
            outChannel.write(buffer);
            buffer.clear();//这个很关键,否则position和limit一样无法写入了,会出现死循环
        }

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

利用transfer方法,简单复制
package bio;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.nio.channels.FileChannel;

public class MyChannel04 {
    public static void main(String[] args) throws Exception {

        FileInputStream in = new FileInputStream("d:/2.jpg");
        FileOutputStream out = new FileOutputStream("d:/美女.jpg");
        FileChannel inChannel = in.getChannel();
        FileChannel outChannel = out.getChannel();
        outChannel.transferFrom(inChannel, 0, inChannel.size());
        in.close();
        out.close();

    }
}

注意
package bio;

import java.nio.ByteBuffer;

public class MyChannel05 {
    public static void main(String[] args) {
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        buffer.putInt(10);
        buffer.putLong(10L);
        buffer.putChar('我');
        buffer.putShort((short) 189);

        buffer.flip();
//        while (buffer.hasRemaining()) {
//            System.out.println(buffer.get());//这样会造成解析都是乱的
//        }
        System.out.println(buffer.getInt());
        System.out.println(buffer.getLong());
        System.out.println(buffer.getChar());
//        System.out.println(buffer.getLong());//Exception in thread "main" java.nio.BufferUnderflowException
        System.out.println(buffer.getShort());

    }
}

利用nio的新特性做一个本地内存的修改
package bio;

import java.io.FileNotFoundException;
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;

public class MyChannel06 {
    public static void main(String[] args) throws Exception {
        RandomAccessFile randomAccessFile = new RandomAccessFile("1.txt", "rw");
        FileChannel channel = randomAccessFile.getChannel();
        MappedByteBuffer map = channel.map(FileChannel.MapMode.READ_WRITE, 0, 5);
        map.put(0, (byte) 'a');
        map.put(1, (byte) 'b');
        randomAccessFile.close();
    }
}

这个并没有自己创建的buffer,而是利用channel来帮我们映射了一个本地内存。我们再修改。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值