一、NIO概述

java.nio全称java non-blockingIO,是指JDK1.4开始提供的新API。从JDK1.4开始,Java提供了一系列改进的输入/输出的新特性,被统称为NIO(即NewIO)。新增了许多用于处理输入输出的类,这些类都被放在java.nio包及子包下,并且对原java.io包中的很多类进行改写,新增了满足NIO的功能。

NIO和BIO有着相同的目的和作用,但是它们的实现方式完全不同,BIO 以流的方式处理数据,而NIO以块的方式处理数据,块I/O的效率比流I/O高很多。另外,NIO是非阻塞式的,这一点跟BIO也很不相同,使用它可以提供非阻塞式的高伸缩性网络。NIO主要有三大核心部分: Channel(通道), Buffer(缓冲区), Selector(选择器)。传统的BIO基于字节流和字符流进行操作,而NIO基于Channel和Buffer(缓冲区)进行操作,数据总是从通道读取到缓冲区中,或者从缓冲区写入到通道中。Selector(选择区)用于监听多个通道的事件(比如:连接打开,数据到达)。因此使用单个线程就可以监听多个数据通道。

二、通道和缓冲区

2.1 概述

通道和缓冲区是NIO中的核心对象,几乎在每一个 I/O 操作中都要使用它们。
通道是对原 I/O 包中的流的模拟。到任何目的地(或来自任何地方)的所有数据都必须通过一个 Channel 对象。一个Buffer 实质上是一个容器对象。发送给一个通道的所有对象都必须首先放到缓冲区中;同样地,从通道中读取的任何数据都要读到缓冲区中。

2.2 什么是缓冲区

Buffer 是一个对象, 它包含一些要写入或者刚读出的数据。 在 NIO 中加入 Buffer 对象,体现了新库与原 I/O 的一个重要区别。在面向流的 I/O 中,可以将数据直接写入或者将数据直接读到 Stream 对象中。

在 NIO 库中,所有数据都是用缓冲区处理的。在读取数据时,它是直接读到缓冲区中的。在写入数据时,它是写入到缓冲区中的。任何时候访问 NIO 中的数据,您都是将它放到缓冲区中。

缓冲区实质上是一个数组。通常它是一个字节数组,但是也可以使用其他种类的数组。但是一个缓冲区不仅仅是一个数组。缓冲区提供了对数据的结构化访问,而且还可以跟踪系统的读/写进程。

2.3 缓冲区类型

最常用的缓冲区类型是 ByteBuffer。一个 ByteBuffer 可以在其底层字节数组上进行 get/set 操作(即字节的获取和设置)。

对于每一种基本 Java 类型都有一种缓冲区类型:

ByteBuffer、CharBuffer、ShortBuffer、IntBuffer、LongBuffer、FloatBuffer、DoubleBuffer

每一个 Buffer 类都是 Buffer 接口的一个实例。 除了 ByteBuffer,每一个 Buffer 类都有完全一样的操作,只是它们所处理的数据类型不一样。因为大多数标准 I/O 操作都使用 ByteBuffer,所以它具有所有共享的缓冲区操作以及一些特有的操作。
ByteBuffer类(二进制数据)该类的主要方法如下:

  1. public abstract ByteBuffer put(byte[] b); 存储字节数据到缓冲区
  2. public abstract byte[] get(); 从缓冲区获得字节数据
  3. public final byte[] array(); 把缓冲区数据转换成字节数组
  4. public static ByteBuffer allocate(int capacity); 设置缓冲区的初始容量
  5. public static ByteBuffer wrap(byte[] array); 把一个现成的数组放到缓冲区中使用
  6. public final Buffer flip(); 翻转缓冲区,重置位置到初始位置

2.4 什么是通道

Channel是一个对象,可以通过它读取和写入数据。拿 NIO 与原来的 I/O 做个比较,通道就像是流。

所有数据都通过 Buffer 对象来处理。一半不会将字节直接写入通道中,相反,是将数据写入包含一个或者多个字节的缓冲区。同样,不会直接从通道中读取字节,而是将数据从通道读入缓冲区,再从缓冲区获取这个字节。

2.5 通道类型

通道与流的不同之处在于通道是双向的。而流只是在一个方向上移动(一个流必须是 InputStream 或者 OutputStream 的子类), 而 通道 可以用于读、写或者同时用于读写。

因为它们是双向的,所以通道可以比流更好地反映底层操作系统的真实情况。特别是在 UNIX 模型中,底层操作系统通道是双向的。

2.6 常用的Channel类

FileChannel、DatagramChannel、ServerSocketChannel 和SocketChannel.
FileChannel用于文件的数据读写,DatagramChannel用于UDP的数据读写,ServerSocketChannel 和SocketChannel用于TCP的数据读写。
这里我们先说说FileChannel类,该类主要用来对本地文件进行IO操作,主要方法如下所示:

  1. public int read(ByteBuffer dst),读取数据并放到缓冲区中
  2. public int write(ByteBuffe[src),把缓冲区的数据写到通道中
  3. public long transferFrom(ReadableByteChannel src, long position, long count),从目标通道中复制数据
  4. public long transferTo(long position, long count, WritableByteChannel target),把数据从当前通道复制给目标通道

三、NIO的文件IO操作

3.1 文件写入

    @Testpublic void test1() throws Exception {//1.创建输出流FileOutputStream fos = new FileOutputStream("test.txt");//2.从流中得到一个通道FileChannel fc = fos.getChannel();//3.提供一个缓冲区ByteBuffer buffer = ByteBuffer.allocate(1024);//4.往缓冲区中存入数据String str = "hello,nio";buffer.put(str.getBytes());//5.翻转缓冲区 需要把指针复位,不然是写入的hello,nio后面的内容buffer.flip();//6.把缓冲区写到通道中fc.write(buffer);//7.关闭fos.close();}

3.1 文件读取

    @Testpublic void test2() throws Exception{File file = new File("test.txt");//1.创建输入流FileInputStream fis = new FileInputStream(file);//2.得到一个通道FileChannel fc = fis.getChannel();//3.准备一个缓冲区ByteBuffer buffer = ByteBuffer.allocate((int) file.length());//4.从通道里读取数据并存到缓冲区中fc.read(buffer);System.out.println(new String(buffer.array()));//5.关闭fis.close();}

3.3 文件复制

    @Testpublic void test3() throws Exception{//1.创建两个流,一个读一个写FileInputStream fis = new FileInputStream("test.txt");FileOutputStream fos = new FileOutputStream(" /Users/pengweiwei/Downloads/test.txt");//2.准备两个通道FileChannel sourceChannel = fis.getChannel();FileChannel destChannel = fos.getChannel();//3.复制destChannel.transferFrom(sourceChannel,0,sourceChannel.size());//4.关闭流fis.close();fos.close();}

NIO详解以及NIO的文件IO操作相关推荐

  1. java nio详解,Java NIO API详解

    Java NIO API详解 在JDK 1.4以前,Java的IO操作集中在java.io这个包中,是基于流的阻塞(blocking)API.对于大多数应用来说,这样的API使用很方 便,然而,一些对 ...

  2. java对文件的操作详解_Java 对 Properties 文件的操作详解及简单实例

    Java 对 Properties 文件的操作详解及简单实例 发布于 2020-8-7| 复制链接 摘记: Java 对 Properties 文件的操作简介在 Java 中,我们常用 java.ut ...

  3. NIO详解(三):IO多路复用模型之select、poll、epoll

    1. 前言 最近在研究基于Java的高性能异步非阻塞I/O框架Netty,因为最近做的RDMAChannel要用到其中的思想.Netty底层是通过大量的NIO实现的,通过分析底层NIO源码,发现NIO ...

  4. java对文件的操作详解,java对各种文件的操作详解

    java中提供了io类库,可以轻松的用java实现对文件的各种操作.下面就来说一下如何用java来实现这些操作. 新建目录 //String URL = request.getRequestURI() ...

  5. Java基础——Java NIO详解(一)

    一.基本概念 1.I/0简介 I/O即输入输出,是计算机与外界世界的一个借口.IO操作的实际主题是操作系统.在java编程中,一般使用流的方式来处理IO,所有的IO都被视作是单个字节的移动,通过str ...

  6. 详解 Java NIO

    详解 Java NIO 文件的抽象化表示,字节流以及字符流的文件操作等属于传统 IO 的相关内容,我们已经在前面的文章进行了较为深刻的学习了. 但是传统的 IO 流还是有很多缺陷的,尤其它的阻塞性加上 ...

  7. Java基础——Java NIO详解(二)

    一.简介 在我的上一篇文章Java NIO详解(一)中介绍了关于标准输入输出NIO相关知识, 本篇将重点介绍基于网络编程NIO(异步IO). 二.异步IO 异步 I/O 是一种没有阻塞地读写数据的方法 ...

  8. Python 文件 IO 操作详解

    Python 文件 IO 操作详解 1.文件 IO 常用操作 2.文件打开操作 2.1 打开命令 2.2 命令参数 2.2.1 路径 2.2.2 mode 2.2.3 buffering 缓冲区 2. ...

  9. 详解C#使用FileSystemWatcher文件监控对象的感受

    ** 详解C#使用FileSystemWatcher文件监控对象的感受 ** 本文和大家一起来学习分享一下C#使用FileSystemWatcher文件监控对象,希望对你有帮助. 最近在项目中有这么个 ...

最新文章

  1. 交换机应用寻找10个完美的因素
  2. 深度残差收缩网络:借助注意力机制实现特征的软阈值化
  3. python爬虫软件-8个最高效的Python爬虫框架,你用过几个?
  4. 小明分享|WiFi协议迭代历程
  5. Java单例的常见形式
  6. 产品设计 产品经理 喜欢的网站
  7. 新型智能芯片防伪印章设备_思格特智能印章管理系统成功签约山东问童动力设备公司...
  8. eix安装_U盘安装原版Windows 8.1
  9. java txt中统计一个字母出现的次数并储存,统计txt文件中每个字符出现的次数,并根据次数从高到低排序...
  10. 单片机简单的计算器c语言程序,AT89S52单片机实现简易计算器(C语言程序)
  11. kafka no record information is available
  12. 高中数学解析几何解题方法,2019高考生没有掌握方法!
  13. 微型计算机补码运算电路特点,二进制数的运算及其加法电路
  14. 二次开发uniswap-01-SDK
  15. qq公众平台出错了609_生鲜农贸行业订单容易出错,生鲜配送管理系统帮您来解决...
  16. Android 线程与线程安全
  17. 英语语法汇总(8.动词)
  18. 2022企业人效管理白皮书
  19. centos及MySQL远程登陆问题
  20. Anaconda Tutorial

热门文章

  1. Matlab中writetable函数的使用
  2. 电子名片,快速打造你的互联网信任度
  3. 网络教育计算机 判断,兰州大学网络教育2018年计算机入学测试模拟题(判断题)...
  4. 【SD2.0大会】达内创始人韩少云:创业就像买股票
  5. python怎么安装开发版_【干货】开发板上安装python的hiai库和opencv库
  6. win安装nginx php mysql_win平台安装配置Nginx+php+mysql 环境
  7. cap流程图_生工技术 | RACE种类、特点及其原理
  8. 网上书店可行性分析报告(原创)
  9. [转]西方重要节日简介
  10. 跟着鬼哥学android java hook(三)