1、NIO介绍

  应用程序中,通常会涉及两种类型的计算:计算密集型和I/O密集型。对多数应用来说,花费在等待IO上的时间是比较大的。因此提高IO操作效率对应用的性能至关重要。

  面向流的IO系统一次处理一个字节的数据,效率低。

  New I/O提供高速、面向块的I/O处理机制,每个操作都产生或消费一个数据块, 按块处理数据比按字节处理数据快得多,只不过处理上少了一点优雅性。

  NIO库在java.nio包中,java.io也以NIO为基础重新实现。

  NIO中核心是通道和缓冲区,绝大部分操作都需要使用它们。

  从一个通道中读取数据:创建缓冲区,通道将数据读取到缓冲区。

  写入:创建缓冲区用数据填充,然后将缓冲区数据写入通道。

  2、通道Channel

  通道是NIO操作的数据操作连接,一旦打开通道,就可以执行读取和写入操作。与流相比,通道的操作使用Buffer对象而不是数组。

  通道提高了IO操作性能,体现在文件和网络操作上。

  通道是对原有IO包中流的模拟,任何来源和去向的数据都必须通过通道对象来读取或写入。

  与流相比,通道是双向的,操作也是双向的,而且可以比流更反映底层操作系统的真实情况。

  重要通道有4个:

  • FileChannel,从文件中读取数据。
  • DatagramChannel,通过UDP读写网络中的数据。
  • SocketChannel,通过TCP读写网络中的数据。
  • ServerSocketChannel,监听新接入的TCP连接,并创建一个SocketChannel。

  3、文件通道

  FileChannel是连接文件的通道,它无法设置为非阻塞模式,即总是工作在阻塞模式下。

  BIO 即阻塞 I/O,不管是磁盘 I/O 还是网络 I/O,数据在写入 OutputStream 或者从 InputStream 读取时都有可能会阻塞。一旦有线程阻塞将会失去 CPU 的使用权,这在当前的大规模访问量和有性能要求情况下是不能接受的。

  在使用FileChannel前,必须先打开它。但是程序无法直接创建FileChannel对象,需要通过InputStream、OutputStream或RandomAccessFile来获取FileChannel实例。

  FileChannel提供了与其他通道之间高效传输数据的能力,比传统的基于流和字节数组作为缓冲的做法,实现起来更加简单快捷。

  碰到的问题:FileChannel是抽象类,抽象类不能实例化是指不能直接通过new来进行实例化。但是如果抽象类通过其它函数获得了一个实例,那肯定是这个函数返回了这个抽象类的一个子类!!!还有就是,抽象类是有构造函数的,子类可以调用。

  文件通道的另一个功能是对文件的部分片段进行加锁。

  当文件上的某个片段上加排他锁后,其他进程必须等待锁释放之后,才能访问该文件的加锁片段。文件通道上的锁是由JVM所持有的,因此适合于与其他应用程序协同访问文件的情况。

  4、缓冲区

  抽象类Buffer及其实现类可以方便地用来创造各种基本数据类型的缓冲区,相对于流式IO中的数组缓冲区,Buffer提供了更加丰富的方法对其中的数据进行操作。

  Buffer代表要写入或者刚读出的数据。NIO中,所有数据都通过缓冲区Buffer对象来处理。

  缓冲区实质上是一个容器,发送给通道的所有数据必须先放入缓冲区;同样,从通道中读取的任何数据都要读到缓冲区。

  从实现的结构看,缓冲区是一个数组,通常是一个字节数组,但是也可以是其他数组。值得注意的是,缓冲区又不仅仅是数组,缓冲区提供了对数据的结构化访问,而且还可以跟踪系统的读/写进程。

  最常用的是ByteBuffer,它在其底层字节数组上进行get和set操作。每一种基本数据类型都有对应的缓冲区类型。除了ByteBuffer,子类的操作是完全一样,只是处理的数据类型不同。

  使用Buffer读写数据的一般步骤:

  1. 装入数据到Buffer;(写)
  2. 调用flip()方法,将Buffer从写模式切换到读模式;
  3. 从Buffer中读取数据;
  4. 调用clear()方法或者compact()方法,清空。

  flip()方法的作用是切换模式。

  compact()方法只会清楚已经读过的数据,任何未读的数据都被移到缓冲区的起始处,新写入的数据将放到缓冲区未读数据的后面。

  5、容量、位置和读写范围

  从实现结构上看,缓冲区是一个数组,通常是一个字节数组,也可以使用其他类型的数组。

  而本质上,缓冲区是一块可以写入数据,然后从中读取数据的内存,这块内存被包装成Buffer对象,并提供一组方法来访问内存。

  6、分散和聚集

  分散读:从通道中读取的数据写入多个Buffer,一次填充满每个缓冲区噢!

  聚集写:把数据从多个缓冲区中写入通道,把一组缓冲区汇聚成单个数据流。

  (多个Buffer保存在缓冲区数组中)

  分散和聚集常用于需要将传输的数据分开处理的场合。例如传输由一个消息头和消息体组成的消息,可以将消息头和消息体分散到不同的Buffer中,方便分开进行处理。

  7、编码与字符集

  Java.nio.charset提供了相关类,可以对编码和解码过程进行精细的控制。

  语言的多样性使得字符需要通过特定的字符集编码,字符集中每个字符会有一个证书编码与其对应。同一个字符集有不同的编码方式,如果某种编码格式产生的字节序列,用另外一种编码格式来解码,就会得到错误的字符,产生乱码!!

  8、通道间的数据传输

  transferForm(fromChannel, position, count)方法可以将数据从源通道直接传入本通道,从position处开始向目标文件写入数据,count为最多传输的字节数。

  transferTo将数据从本通道传输到其他通道,该方法可以实现文件的复制。

Java New IO的更多相关文章

  1. java的IO流

    java的IO流继承四大抽象类分别是字节流 inputStream outputStream与字符流 read write.怎么理解记忆很重要. 直接连接读写对象的是结点流,例如对文件读取字节类的名字 ...

  2. java之io之File类的list()方法过滤目录的使用

    java的io的知识中,File类必须掌握.File类是对文件或者文件夹的封装.它本身并不能对所封装的文件进行读写,它封装的只是文件或文件夹的周边知识,比如 大小啦,创建日期啦,路径啦等等. 如果Fi ...

  3. Java 新IO

       NIO提供全新的底层I/O模型.与最初的java.io包中面向流(stream-oriented)概念不同,NIO采用了面向块的概念(block-oriented).在尽可能的情况下,I/O的操 ...

  4. JAVA中IO总结

    JAVA中IO流主要分为两大类: 字节流:InputStream+OutputStream 字符流:Reader+Writer 字节流: InputStream是所有字节输入流的父类 OutputSt ...

  5. Java基础——IO流

    今天刚刚看完java的io流操作,把主要的脉络看了一遍,不能保证以后使用时都能得心应手,但是最起码用到时知道有这么一个功能可以实现,下面对学习进行一下简单的总结: IO流主要用于硬板.内存.键盘等处理 ...

  6. 【Java】IO流简单分辨

    转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/5827509.html Java的IO流体系十分庞大,并且体系层次稍复杂,很容易记混或记错.在此,我把平时经常用 ...

  7. JAVA中IO技术:BIO、NIO、AIO

    1.同步异步.阻塞非阻塞概念        同步和异步是针对应用程序和内核的交互而言的. 阻塞和非阻塞是针对于进程在访问数据的时候,根据IO操作的就绪状态来采取的不同方式,说白了是一种读取或者写入操作 ...

  8. Java - 文件(IO流)

    Java - 文件 (IO)   流的分类:     > 文件流:FileInputStream | FileOutputStream | FileReader | FileWriter     ...

  9. JAVA的IO运用

    IO OF JAVA想写好一篇关于JAVA的IO的文章不容易,因为它涉及的东西很多难以写得有深度和有思路.我虽不才但也写.这篇文章有我个人不少的见解,虽然涉足计算机不深但我不想用一大堆这个可能那个可能 ...

  10. JAVA的IO学习

    IO 有具体的分类: 有具体的分类:1:根据处理的数类型不同:字节流和字符流.2:根据流向不同:输入流和输出流. =============(补充字节跟字符概念区分)================= ...

随机推荐

  1. Spring AOP潜入易懂的讲解

    为什么会有面向切面编程(AOP),我们知道Java是一个面向对象(OOP)的语言,但它有一些弊端,比如当我们需要为多个不具有继承关系的对象引入一个公共行为,例如日志,权限验证,事务等功能时,只能在每个 ...

  2. 转载:在Excel中将数据库字段转换成驼峰式

    转载地址 在Excel中将数据库字段转换成驼峰式 1.将数据库字段复制到Excel表格第一列: 2.在第二列顶部输入=PROPER(A1)命令: 3.在第三列顶部输入=SUBSTITUTE(B1,&q ...

  3. Leetcode题目48.旋转图像(中等)

    题目描述: 给定一个 n × n 的二维矩阵表示一个图像. 将图像顺时针旋转 90 度. 说明: 你必须在原地旋转图像,这意味着你需要直接修改输入的二维矩阵.请不要使用另一个矩阵来旋转图像. 示例 1 ...

  4. 使用create-react-app创建项目(二)——引入ant方法(一)

    扩展项目(需要创建git默认文件) 具体步骤如下:       a.git init       b.git add .       c.git commit -m "..." n ...

  5. cs231n lecture2 image classification

    1.图片分类若采用最近邻法: import numpy as np class NearestNeighbor: def _init_(self): pass def train(self, X, y ...

  6. 线上应用接入sentinel的第一个流控规则

    sentinel接入第1个应用A以及控制台,已经上线一段时间了,本周接入了第2个应用B: 因为测试同学只有几个,没有压测团队.测试平台.. 各接口能承载的最大qps不确定 ,接入的应用暂时都没有配置规 ...

  7. redis4. dict字典

    基础数据结构: (注意dict是字典,dict->type是相关函数指针, dict->type->keyDup是执行该方法) 具体调用链路: 渐进式rehash: 新增/删除时: ...

  8. 开机自动挂载ISO文件

    开机自动挂载ISO文件 Table of Contents 1. 概述 1.1. 通过fstab 1.2. 通过rc.local 1 概述 开机自动挂载ISO 文件有两种途径 .一种是通过配置fsta ...

  9. Kafka相关概念及核心配置说明

    1. Kafka简介 Kafka是最初由Linkedin公司开发,是一个分布式.支持分区的(partition).多副本的(replica),基于zookeeper协调的分布式消息系统,它的最大的特性 ...

  10. Java 连接Access

    Java 连接Access 第一次使用连接Access数据库, 记录一下遇到的坑 Access驱动下载地址 http://pan.baidu.com/s/1o8ltTfc 不使用WINDOW的建立数据 ...