java NIO

一、NIO定义

Java NIO (New IO,Non-Blocking IO)是从Java 1.4版本开始引入的一套新的IO API,可以替代标准的Java IO API。NIO与原来的IO有同样的作用和目的,但是使用的方式完全不同,NIO支持面向缓冲区的、基于通道的IO操作。NIO将以更加高效的方式进行文件的读写操作。

1.1 核心

通道和缓冲区(Buffer)和Selector,通道表示IO源到IO设备(例如:文件,套接字)的连接,缓冲区底层就是数组

二、Buffer

2.1 定义

一个用于特定基本类型数据的容器。
缓冲区是特定基本类型元素的线性有限序列。

2.2 性质

缓冲区的容量 是它所包含的元素的数量。缓冲区的容量不能为负并且不能更改。
缓冲区的限制 是第一个不应该读取或写入的元素的索引。缓冲区的限制不能为负,并且不能大于其容量。
缓冲区的位置 是下一个要读取或写入的元素的索引。缓冲区的位置不能为负,并且不能大于其限制。

2.3 常用方法

  • Buffer flip()
    翻转这个缓冲区。
    使position指向0位置,limit的位置则不变,为文件的读取做准备。
  • Buffer clear()
    清除此缓冲区。
    使position指向0的位置,limit指向最大的位置

三、参考

3.1 参考

真正理解IO

3.1 传统的阻塞I/O模型

  • 一个请求需要一个线程区处理
  • 阻塞I/O模式下会有大量的线程被阻塞,的导致系统的利用率很差。
  • 网络I/O阻塞和网络故障可能导致线程等待的时间更长。

3.2 IO与NIO的区别

  • 原有的 IO 是面向流的、阻塞的,(阻塞就是该线程调用read或者wirte方法,直到读到数据或者写出某些数据,不然线程一致会阻塞在这个地方,不能做其他的事情。)NIO 则是面向块的、非阻塞的。(非阻塞就是读取数据时有自己所要的数据的时候就读取,没有自己所要的数据的时候还可以去做其他的事情)。也就是可以一个线程去处理多个操作,而不是1000个线程过来就需要创建1000个线程去处理。
  • 原来的IO流不存在缓存的概念,NIO提供缓存的概念,数据被存储在缓存中,可以前后移动来读取所要的数据。

3.3 通道和流的比较

  • 通道可以同时进行读和写,而流只能进行度和写。
  • 通道可以异步实现读取数据
  • 通道可以从缓冲区读数据,也可以写数据到缓冲区。

3.4 读写数据需要注意的问题

  • 使用flip方法进行读写模式的转换,将写模式转换为读模式
  • 使用clear方法将已经从缓冲区去获取的的数据进行清除。

3.5 常用的字段

  • capacity
    缓冲区的容量

  • position
    当前读写的位置

  • limit
    信息末尾的位置

3.6 缓冲区常用的方法

  • clear方法
    清空缓存区
  • compact方法
    只会清空已经读取的数据
  • flip方法
    向缓存区写变为从缓存区读的状态
  • put方法
    将字节类型的数据放到缓冲区中
  • get方法
    取出缓存去中的字节,一次只能取一个
    在这里插入图片描述

3.7 Selector

可以检测出多个NIO通道,并看看读写是否就绪,多个channel以事件的形式注册到同一个selector,从而使一个线程处理多个请求成为可能。

四、实战操作

4.1 传统的IO读写

字节流

public class ReadTest
{
    public static void main(String[] args) throws IOException {
        FileInputStream fileInputStream = null;
        try {
            fileInputStream = new FileInputStream("C:\\Users\\ybx\\IdeaProjects\\QuickKill\\src\\main\\java\\com\\example\\demo\\IO\\ReadTest.java");
            byte[] bytes = new byte[1024];
            int len = 0;
            while ((len = fileInputStream.read(bytes))!= -1){
                System.out.println(new String(bytes));
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }finally {
            fileInputStream.close();
        }
    }
}

字符流:

public class ReadTest
{
    public static void main(String[] args) throws IOException {
        FileReader read = null;
        try {
            read = new FileReader("C:\\Users\\ybx\\IdeaProjects\\QuickKill\\src\\main\\java\\com\\example\\demo\\IO\\ReadTest.java");
            char[] array = new char[1024];
            while (read.read(array) != -1){
                System.out.println(new String(array));
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }finally {
            read.close();
        }
    }
}

使用BufferReader对象进行读写:

public class ReadTest
{
    public static void main(String[] args) throws IOException {
        BufferedReader read = null;
        try {
            read = new BufferedReader(new FileReader("C:\\Users\\ybx\\IdeaProjects\\QuickKill\\src\\main\\java\\com\\example\\demo\\IO\\ReadTest.java"));
            String line = null;
            while ((line = read.readLine()) != null){
                System.out.println(line);
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }finally {
            read.close();
        }
    }
}

4.2 使用NIO进行读写

public class ReadTest
{
    public static void main(String[] args) throws IOException {
        FileInputStream fileInputStream = new FileInputStream("C:\\Users\\ybx\\IdeaProjects\\QuickKill\\src\\main\\java\\com\\example\\demo\\IO\\ReadTest.java");
        FileChannel channel = fileInputStream.getChannel();
        ByteBuffer allocate = ByteBuffer.allocate(1024);
        while (channel.read(allocate) != -1){
            //读写模式转换
            allocate.flip();
            while (allocate.hasRemaining()){
                System.out.print((char)allocate.get());
            }
            allocate.compact();
        }
        channel.close();
    }
}

4.3 参考

Java NIO?看这一篇就够了!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值