#java#nio#nio的基本概念

NIO 1: jsr51, jdk 1.4的时候引入
NIO1

NIO2: jsr 203

JDK 7的时候引入

NIO2

在这里插入图片描述
NIO2的时候引入了异步 io ,也就是 Asynchronous IO

java bio 是面向流的,没有缓存区的,属于阻塞IO

nio 是面向缓冲区的, 有一个 selectors选择器的概念

NIO 3大核心组件

  1. buffer
  2. channel
  3. selector

在这里插入图片描述
在这里插入图片描述
java nio 复杂的地方就是 读写模式混合在一起了,放到了一个数组里面
在这里插入图片描述

通过 flip 操作 进行读写操作 的切换

java NIO 有一个概念,就是 通过 JNI 直接申请一块堆外内存操作

实际上是调用了 C++ 的 mallocate来分配了内存,因此这种没办法被虚拟机回收,因为是堆外内存
在这里插入图片描述

因为用了直接内存,所有减少了数据拷贝的操作

在这里插入图片描述
在这里插入图片描述

实例代码

public class MainTest1 {
    public static void main(String[] args) throws IOException {

        FileInputStream in = new FileInputStream("D:\\模板\\nio\\nio\\src\\main\\resources\\a.txt");
        // File file;
        FileOutputStream out = new FileOutputStream("D:\\模板\\nio\\nio\\src\\main\\resources\\b.txt");
        FileChannel fin = in.getChannel();
        FileChannel fout = out.getChannel();
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        while (true) {
            buffer.clear();
            int flag = fin.read(buffer);
            if (flag == -1) {
                break;
            }
            buffer.flip();
            fout.write(buffer);
        }
        in.close();
        out.close();

    }

}

  public static void main(String[] args) throws IOException {


        FileChannel in = FileChannel.open(Paths.get(("D:\\ASUS\\Desktop\\后台管理模板\\nio\\nio\\src\\main\\resources\\a.txt")), StandardOpenOption.READ);
        // File file;
        FileChannel out = FileChannel.open(Paths.get(("D:\\ASUS\\Desktop\\后台管理模板\\nio\\nio\\src\\main\\resources\\b.txt")),StandardOpenOption.WRITE);
        out.transferFrom(in,0,in.size());


    }

下面是 基于 nio的 echo server的简单实现

public class ServerTest2 {
    public static void main(String[] args) throws Exception {
        ServerSocketChannel ch = ServerSocketChannel.open();
        ch.configureBlocking(false);
        ch.bind(new InetSocketAddress(8888));
        Selector selector = Selector.open();
        ch.register(selector, SelectionKey.OP_ACCEPT);
        while (selector.select() > 0) {
            Iterator<SelectionKey> it = selector.selectedKeys().iterator();
            //遍历所有注册的选择键
            while (it.hasNext()) {
                SelectionKey k = it.next();//获取准备就绪的事件
                if (k.isAcceptable()) {
                    System.out.println("accept");
                    SocketChannel cli = ch.accept();
                    //切换客户端为非阻塞模式
                    cli.configureBlocking(false);
                    //将通道注册到这个选择器上
                    cli.register(selector, SelectionKey.OP_READ);
                } else if (k.isReadable()) {
                    // System.out.println("read ..");
                    //可以接收事件
                    //获取选择器上可以读的通道
                    SocketChannel cl = (SocketChannel) k.channel();
                    ByteBuffer  bf = ByteBuffer.allocate(1024);
                    int f = 0;
                    while ((f=cl.read(bf))>0) {
                        System.out.println("read .");
                        bf.flip();
                        System.out.println(new String(bf.array(),0,f));
                        bf.clear();
                    }
                }
                it.remove();//取消选择键

            }
        }
    }
}

public class MainTest1 {
    public static void main(String[] args) throws IOException {

        SocketChannel socketChannel = SocketChannel.open(
                new InetSocketAddress("127.0.0.1",8888)
        );
        socketChannel.configureBlocking(false);
        ByteBuffer bf = ByteBuffer.allocate(1024);
        bf.put(new Date().toString().getBytes());
        //切换成都模式
        bf.flip();
        //将数据写入
        socketChannel.write(bf);
        bf.clear();
        socketChannel.close();

    }

}

下面是基于UDP 的写法

public static void main(String[] args) throws IOException {

        // SocketChannel socketChannel = SocketChannel.open(
        //         new InetSocketAddress("127.0.0.1",8888)
        // );
        DatagramChannel socketChannel = DatagramChannel.open();
        socketChannel.configureBlocking(false);
        ByteBuffer bf = ByteBuffer.allocate(1024);
        bf.put(new Date().toString().getBytes());
        //切换成都模式
        bf.flip();
        //将数据写入
        socketChannel.write(bf);
        bf.clear();
        socketChannel.close();

    }

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看REAdMe.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看REAdMe.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看READme.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值