乐趣区

关于java:Java基础NIO-初步了解

NIO(Non-blocking I/O,在 Java 畛域,也称为 New I/O),是一种同步非阻塞的 I / O 模型,也是 I / O 多路复用的根底。那和一般 IO 有什么区别呢?

一、概述

NIO 是从 Java 1.4 版本开始引入的一个新的 IO API,NIO 反对面向缓冲区的、基于通道的 IO 操作。
原来的 IO 是阻塞式 IO,与 NIO 的比照:

IO NIO
面向流 面向缓冲
阻塞 IO 非阻塞 IO
选择器

1、面向流和面向缓冲
面向流是每次从流中读取一个或多个字节,直到读取完。读过了就过了。
面向缓冲是把数据先放到缓冲区中,须要读取的时候从缓冲区拿,缓冲区数据读取后还在,还能通过指针挪动读取缓冲区中不同的数据。

2、阻塞 / 非阻塞
阻塞就是不读写数据的时候也要占着线程,不能干别的。非阻塞是不读写的时候该线程能够干别的事件。

3、选择器
容许一个线程治理多个输出通道。

解决数据的流程:
阻塞 IO

二、NIO 根底

Buffer Channel 是规范 NIO 中的外围对象。

  • Channel 是对原 IO 中流的模仿,任何起源和目标数据都必须通过一个 Channel 对象
  • Buffer 本质上是一个容器对象,发给 Channel 的所有对象都必须先放到 Buffer 中;同样的,从 Channel 中读取的任何数据都要读到 Buffer 中。

一)对于 Buffer

Buffer 蕴含一些要写入或读出的数据。在 NIO 中,所有的数据都是用 Buffer 解决的,它是 NIO 读写数据的直达池。Buffer 本质上是一个数组,提供对数据结构化拜访的性能。
应用 Buffer 读写数据个别有以下四个步骤:

  1. 写入数据到 Buffer;
  2. 调用 flip() 办法,从写模式转换为读模式;
  3. 从 Buffer 中读取数据;
  4. 调用 clear() 办法(清空);或者 compact() 办法(革除已读数据)。

二)对于 Channel

能够通过 Channel 读取和写入数据。能够把它看做 IO 中的流。然而它和流相比还有一些不同。

  • Channel 是双向的,既能够读又能够写,而流是单向的
  • Channel 能够进行异步的读写
  • 对 Channel 的读写必须通过 buffer 对象

三、案例 demo

上面通过一个案例解说 NIO 的操作过程。
将从一个文件中读取数据,写入到另一个文件中,代码如下

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

public class CopyFileUseNIO {public static void main(String[] args) throws IOException {
        String src = "/xxxx/LICENSE.txt";
        String dst = "/xxxx/LICENSE-COPY.txt";

        FileInputStream fi = new FileInputStream(src);
        FileOutputStream fo = new FileOutputStream(dst);

        // 取得传输通道 channel
        FileChannel inChannel = fi.getChannel();
        FileChannel outChannel = fo.getChannel();

        // 取得容器 buffer
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        while (true) {
            // 判断是否读完文件
            int eof = inChannel.read(buffer); // #1
            if (eof == -1) {break;}
            // 重设一下 buffer 的 position=0,limit=position
            buffer.flip();        // #2
            // 开始写
            outChannel.write(buffer);  // #3
            // 写完要重置 buffer,重设 position=0,limit=capacity
            buffer.clear();  // #4}

        inChannel.close();
        outChannel.close();
        fi.close();
        fo.close();}
}

关注下面有正文的 #1 ~ #4 四个地位。
四个地位代码执行后 buffer 数据如下所示,参考上面的能够帮你更好的了解,几个操作都做了什么事件。

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

四、总结

本节对 NIO 进行了简要介绍。与原 IO 进行了比照,对 NIO 的读写流程进行了介绍,解说了 NIO 重要的概念 buffer 和 channel。所有的数据必须通过 buffer 解决,channel 仅是连贯的管道,不能间接从 channel 中获取数据。
NIO 有非阻塞的个性,不会在读写未结束时继续阻塞线程,当未在读写时,线程能够解决别的事件。
最初提供了读写数据的 demo 帮忙了解。


参考文章:
Java NIO 浅析
Java 常见面试题汇总 ———–Java 根底(NIO 与 IO 的区别)
Java NIO 详解(一)

退出移动版