一、IO与NIO的区别:

  前提我们先说一说java IO: 

  Java中使用IO(输入输出)来读取和写入,读写设备上的数据、硬盘文件、内存、键盘......,根据数据的走向可分为输入流和输出流,这个走向是以内存为基准的,即往内存中读数据是输入流,从内存中往外写是输出流。

  根据处理的数据类型可分为字节流和字符流:

  1.字节流可以处理所有数据类型的数据,在java中以Stream结尾

  2.字符流处理文本数据,在java中以Reader和Writer结尾。

我们来看个IO流的详解图:

  1.NIO的起源:

    java.NIO是jdk1.4是提出,jdk1.7进行二次改进的java新型IO类,其最大的特点就是它的非阻塞性。

  2.IO与NIO结构差异:

    普通的IO是面向流(Stream Oriented),而NIO则是面向缓冲区(Buffer Oriented)。IO流是单向的,直接面向字节流,通过InputStream、OutputStream来完成数据的输入输出。而NIO是双向的,通过建立通道(Channel),然后将数据装在缓冲区(Buffer)在通道上进行传输。针对不同类型的数据有不同的Buffer,根据数据类型不同(boolean 除外),提供了相应类型的缓冲区: ByteBuffer、CharBuffer、ShortBuffer、IntBuffer、LongBuffer、 FloatBuffer、DoubleBuffer。

二、NIO的Buffer的数据存取:

  1.创建Buffer实例:

ByteBuffer buf = ByteBuffer.allocate(1024); //1024为capacity,通过allocate()方法可以获取一个缓冲区

  2.Buffer类属性的解析:

    Buffer类中有三个属性必须理解:capacity(容量)、limit(访问范围)、position(位置,表示缓冲区中正在操作数据的位置)。通过get(),put()方法进行数据的存取。

    通过flip()方法切换成读模式,clear()方法清空缓冲区。但是缓冲区中的数据依然存在,但是处于“被遗忘”状态,rewind()可重复读。

  3.Buffer的分类:

    Buffer分为直接缓冲区和非直接缓冲区。非直接缓冲区 通过allocate()方法分配缓冲区,将缓冲区建立在JVM的内存中。直接缓冲区 通过allocateDirect()方法,将缓冲区建立在物理内存中。这样做可以提高IO效率,节省了copy的过程,直接缓冲区是物理内存映射文件,但是写入过程不受控制,读过程受GC影响!

三、通道的原理与获取:

  1.通道的原理:

    传统的javaIO是通过DMA的方式存取,这种方式需要CPU的权限。而通道(Channel)自带处理器,不需要去访问CPU,所以在进行大量IO时效率更高一些。通道用于源节点与目标节点的连接。在 Java NIO 中负责缓冲区中数据的传输。Channel 本身不存储数据,因此需要配合缓冲区进行传输。

  2.通道的获取:

    通道的主要实现类 java.nio.channels.Channel 接口:FileChannel、SocketChannel、ServerSocketChannel、DatagramChannel。

    获取通道的方法:

      1)各IO有自己的获取方法、

      2)jdk1.7的NIO2,针对各个通道提供了静态方法open();

      3)jdk1.7的NIO2的Files工具类的newByteChannel();

四、通道的数据传输:

  1.分散(Scatter)与聚集(Gather):  

    1)分散读取(Scattering Reads),将Channel中读取的数据分散到Buffer
    2)聚集写入(Gathering Writes),将多个Buffer中的数据聚集到Channel中

  2.实例代码:

        RandomAccessFile raf1 = new RandomAccessFile("1.txt", "rw");
//1. 获取通道
FileChannel channel = raf1.getChannel();
//2. 分配指定大小的缓冲区
ByteBuffer buf1 = ByteBuffer.allocate(250);
ByteBuffer buf2 = ByteBuffer.allocate(500);
//3. 分散读取
ByteBuffer[] bufs = {buf1, buf2};
channel1.read(bufs);
for (ByteBuffer byteBuffer : bufs) {
byteBuffer.flip();
}
System.out.println(new String(bufs[0].array(), 0, bufs[0].limit()));
System.out.println("-----------------");
System.out.println(new String(bufs[1].array(), 0, bufs[1].limit()));
//4. 聚集写入
RandomAccessFile raf2 = new RandomAccessFile("2.txt", "rw");
FileChannel channel2 = raf2.getChannel();
channel2.write(bufs);

五、字符集 Charset:

  编码:字符串->字节数组。解码:字节数组->字符串

  1.查看Charset里都有哪些编码:

        Map<String, Charset> map = Charset.availableCharsets();
map.forEach((k,v)->{
System.out.println(k);//常见的UTF-8等等..
});

  2.缓冲区编解码:

        Charset c = Charset.forName("UTF-8");
CharsetEncoder e = cs1.newEncoder(); //获取编码器
CharsetDecoder d = cs1.newDecoder(); //获取解码器
CharBuffer buf = CharBuffer.allocate(1024);
buf.put("二狗子到此一游");
buf.flip();
ByteBuffer bBuf = e.encode(buf );//编码
bBuf.flip(); //解码
CharBuffer buf2= d.decode(bBuf);
System.out.println(buf2.toString());

六、阻塞与非阻塞:

  阻塞与非阻塞式的,相较于网络通信:
    1)阻塞:C端发送S端读写请求,S端考虑,阻塞,服务端不会做其他事情,解决方式多线程
    2)非阻塞:Selector(选择器),通道会注册到选择器上,Selector监控IO状况,只有C端准备就绪

Java关于NIO类的详解的更多相关文章

  1. JAVA中StringBuffer类常用方法详解

    String是不变类,用String修改字符串会新建一个String对象,如果频繁的修改,将会产生很多的String对象,开销很大.因此java提供了一个StringBuffer类,这个类在修改字符串 ...

  2. Java日期工具类DateUtils详解(转)

    jar包 appache下的 common-lang3 一. 对指定的日期新增年.月.周.日.小时.分钟.秒.毫秒 public static Date addDays(Date date, int ...

  3. 在java poi导入Excel通用工具类示例详解

    转: 在java poi导入Excel通用工具类示例详解 更新时间:2017年09月10日 14:21:36   作者:daochuwenziyao   我要评论   这篇文章主要给大家介绍了关于在j ...

  4. 《手把手教你》系列基础篇(九十七)-java+ selenium自动化测试-框架设计篇-Selenium方法的二次封装和页面基类(详解教程)

    1.简介 上一篇宏哥介绍了如何设计支持不同浏览器测试,宏哥的方法就是通过来切换配置文件设置的浏览器名称的值,来确定启动什么浏览器进行脚本测试.宏哥将这个叫做浏览器引擎类.这个类负责获取浏览器类型和启动 ...

  5. java中的io系统详解 - ilibaba的专栏 - 博客频道 - CSDN.NET

    java中的io系统详解 - ilibaba的专栏 - 博客频道 - CSDN.NET 亲,“社区之星”已经一周岁了!      社区福利快来领取免费参加MDCC大会机会哦    Tag功能介绍—我们 ...

  6. Java中的main()方法详解

    在Java中,main()方法是Java应用程序的入口方法,也就是说,程序在运行的时候,第一个执行的方法就是main()方法,这个方法和其他的方法有很大的不同,比如方法的名字必须是main,方法必须是 ...

  7. Java虚拟机之垃圾回收详解一

    Java虚拟机之垃圾回收详解一 Java技术和JVM(Java虚拟机) 一.Java技术概述: Java是一门编程语言,是一种计算平台,是SUN公司于1995年首次发布.它是Java程序的技术基础,这 ...

  8. 使用Java操作文本文件的方法详解

    使用Java操作文本文件的方法详解 摘要: 最初java是不支持对文本文件的处理的,为了弥补这个缺憾而引入了Reader和Writer两个类 最初java是不支持对文本文件的处理的,为了弥补这个缺憾而 ...

  9. Java面试题04-final关键字详解

    Java面试题04-final关键字详解 本篇博客将会讨论java中final关键字的含义,以及final用在什么地方,感觉看书总会有一些模糊,而且解释的不是很清楚,在此做个总结,以备准备面试的时候查 ...

随机推荐

  1. MySQL查询(未完结)

    MySql查询 单表查询: 查询所有字段 SELECT * FROM 表名; '*' 代表所有字段 查询指定字段 SELECT 字段名1, 字段名2 FROM 表名; 按照指定条件查询记录 1. 查询 ...

  2. HDD 机械硬盘 安装 linux(centos7)

    1. 下载 UltraISO 文件-->打开, 选中centos.iso镜像;   启动-->写入硬盘映像-->硬盘驱动器(选中u盘)写入方式(USB-HDD+v2)-->写入 ...

  3. asp.net core 错误定位 & vs2017 远程调试部署在centos上的asp.net core程序

        前言 程序运行中会出现各种BUG. 排除BUG有三种方式. 一.访问页面直接报错误信息 出于安全,服务器是关闭这个功能的.在centos上可以用 命令设置环境变量来解决:   export A ...

  4. jQuery ajax调接口时跨域

    解决方法提炼 一.jsonp方法 在前端ajax配置jsonp参数,在后台配置jsonp设置,具体方法自行百度 二. 参考同源策略 把前端静态页面放在tomcat内webapp下,和后台文件同目录, ...

  5. arcgis 地理国情建库软件已完成

    arcgis 地理国情软件已完成: 1.创建1:25000(或则其他比例尺)国家2000坐标系接合表 2.按照地理国情普查数据库标准,创建标准数据库 3.外业调查工作底图制作 4.矢量和影像数据批量裁 ...

  6. GetVersion和GetVersionEx

    原文:http://www.cnblogs.com/VOIP/archive/2011/03/22/1990927.html Windows API 中有两个函数可以得到系统版本信息:GetVersi ...

  7. Unity使Text 文字逐个出现

    Text tex; string s="Unity使Text 文字逐个出现"; //字符出现间隔 waitTime = 0.3f; // float speed=0; //方法一 ...

  8. arm汇编学习(六)---跳转到thumb状态

    通常函数返回使用 pop {r7,pc}或bx lr等方式(bx,b类似jmp为跳转指令,但bx可以指定跳转区域究竟为thumb还是arm指令.thumb指令指令的时候,直接填写该地址却总是产生SIG ...

  9. 利用Grahics 进行图片裁剪

    这两天做了一个图片对比工具,里面要处理两张大的图片,所以要对图片先进行裁剪最开始用了 /// <summary>        /// 裁剪图片        /// </summa ...

  10. c# BackGroundWorker 多线程操作的小例子 (转)

    在我们的程序中,经常会有一些耗时较长的运算,为了保证用户体验,不引起界面不响应,我们一般会采用多线程操作,让耗时操作在后台完成,完成后再进行处理或给出提示,在运行中,也会时时去刷新界面上的进度条等显示 ...