本文主要讲述下自己对IO的理解,对IO的用法和细则可能没有顾虑到。

本文的理解基于以下几篇文章,他们对各自部分都讲的很细,对我理解IO提供了很大帮助。

https://www.cnblogs.com/ylspace/p/8128112.html

该文主要讲解了Java IO的类体系以及他们各自的用处。

https://www.jianshu.com/p/03852a291c56

https://blog.csdn.net/fcbayernmunchen/article/details/8635427#commentBox

https://blog.csdn.net/cringkong/article/details/80274148

这些文章讲解了有关Java Buffer的原理,包括allocate、allocateDirect、map等不同IO方式他们的底层知识。

https://blog.yoodb.com/yoodb/article/detail/1498

该文章浅谈了NIO、AIO的知识。

正文

  首先是我整理的思维导图

IO的理解

  要理解Java IO设计得先了解系统IO,系统不允许程序直接访问硬盘,而是先将用户所需数据准备在系统缓冲区中再转移到用户内存,所以系统IO操作经过三个地方,1、硬盘 2、系统缓冲 3、用户进程空间。File就像是对硬盘的抽象,而stream/reader/writer就是对系统缓冲的抽象,而我们用的Buffer就是用户进程空间的抽象。

  IO的体系结构也是很直观的,对应字节处理和字符处理有了字节流inputstream、outputsream及字符流reader、writer。其中inputsream和reader对应输入流,outputsream、writer对应输出流。

根据接受或写出通道的不同,每个IO流类下衍生出了很多细分类用于处理不同通道。数据来源可以有如下:file、char[]、byte[]、网络流等。

装饰者模式

  在IO类中有一些类叫FilterXX及它的子类即是装饰者,比如我们常用的BufferInputSream和BufferOutStream,它可以自动帮我们建立并管理线程中的buffer。

  那么什么是装饰者模式呢?

  首先搞清楚装饰者的目的是:动态、透明地将责任附加到对象上,若要扩展功能,装饰者提供比继承更有弹性的替代方案。为了跟装饰前看起来一样,它和被装饰者共同装配了的同个接口,为了透明增加功能,它持有了被装配对象(其实是接口),它的方法包括了装饰功能和唤醒被装饰者的方法。

Why Decorator?

  装饰者的目的是对类进行拓展,这跟继承的目标相似。他们特点是什么呢?

l  动态性 装饰者对象可以在程序运行阶段根据需求动态的拓展功能,那个类需要拓展功能只要将相应装饰类组合进去。而继承则需要编译阶段就准备好所有可能性将各种组合可能性编译好进行选择。这会造成类冗杂。

l  解耦性 如果是集成需要层层继承,而上层类的功能改变势必会影响下级类的功能。装饰者则不会。

l  装饰者(和继承)可以在被装饰者的行为上扩展行为,也可以完全替代被装饰者的行为.

l  装饰者会导致设计中出现许多小对象,如果过度使用,会让程序变得很复杂。

l  当只能获取类对象没有class文件时只能用装饰者模式进行加强。

NIO的理解

  NIO是一种非阻塞式的IO,要理解它我们得先解决几个概念。

系统IO阶段: 1、数据准备阶段(系统从磁盘读取) 2、将系统缓冲数据转移到用户本地内存阶段。

什么是阻塞?非阻塞?

答:阻塞非阻塞注重的是数据准备阶段线程有没有造成线程等待,如果数据准备阶段线程需一直等待则是阻塞的,否则是非阻塞。

什么是同步?异步?

答:同步异步注重的是整个IO过程有没有造成IO等待,一些非阻塞IO虽然系统准备阶段没有造成等待,但将数据从内核缓冲区转移到用户内存里还是需要等待。

五种IO模型

由于篇幅有限,不重点讲IO模型,观点基于《UNIIX网络编程卷1:套接字联网API》 第六章。

同步阻塞IO:会造成整个IO过程等待。

同步非阻塞IO:系统准备数据阶段不会造成等待。

信号式IO:系统准备阶段不会造成等待,并且系统准备完成会发送信号给线程。

IO复用:由一个线程管理多个IO,底层调用时select和epoll(select需论询,epoll信号驱动),多个IO只要有一个准备好就线程就不会被阻塞,有效减少了系统准备阶段等待时间。

异步IO:整个IO无需等待。完成时返回成功指示。

  回到我们整体NIO,很明显NIO借用的是IO复用的思想。NIO常使用的三个类即是Selector、Buffer、Channel 。使用的方式就是将Channel注册到selector内,轮询到那个IO可用就在Channel和Buffer间进行读写信息。

  Selector有三种选择方法:select()、select(long timeout)、selectNow();前两种是阻塞式的,如果一个都没准备好还是会被阻塞,selectNow()是非阻塞式的,它能立即返回是否准备好的信号。

  同样继承AbstractSelectableChannel也可以通过设置configureBlocking(false)达到非阻塞的目的。我有一个疑问就是selectNow()+非阻塞Channel是否已经达到异步了呢?因为任何一个过程都没造成等待。当然具体以后再细究,因为Channel 是native代码。。。。

NIO中的Buffer分配方式,ByteBuffer.allocate()、ByteBuffer().allocateDirect()以及MappedByteBuffer、TransrferTo()

  普通IO方式是通过ByteBuffer.allocate(),在  Java堆上分配内存,因此系统IO过程是:硬盘→系统缓冲→用户内存空间→系统缓冲→硬盘。

  而ByteBuffer().allocateDirect()则是在native堆上分配内存,减少了native堆到Java堆中的复制,加快了速度,但也失去了Java GC的便利性。

  MappedByteBuffer:直接建立用户空间与硬盘间的映射,IO过程省略了数据复制到系统内核缓冲的步骤。这里有个问题是为什么需要系统内核缓冲?因为我们IO时往往会继续读取局部上下文,系统为了提高IO效率,直接在内核建立缓冲区缓冲IO数据的上下文以便接下来使用,但如果我们要IO大文件,文件大小超过系统缓冲,这样缓冲区显然是无意义的,因此有了这种方法来解决大文件的IO。

  TransferTO() 它是以上方法的包装,如果传递对象是FileChannel,则使用MappedByteBuffer的方式,如果是其他channel则使用allocateDirect()方式。

AIO

  AIO是完全的异步IO,它实现的核心是异步通道AsynchronizedXXChannel和获取异步结果的接口Future。

  异步通道进行读写时会另开一个线程进行IO操作,操作完成它会将改变接受结果类的完成信号并且将结果赋予到接收结果类(Future)上,我们需要结果时,通过访问接收类信号量,是则获取结果。

Java IO、NIO、AIO知识总结的更多相关文章

  1. 一文理解Java IO/NIO/AIO

      目录 概述 一.IO流(同步.阻塞) 二.NIO(同步.非阻塞) 三.NIO2(异步.非阻塞) 正文 概述 在我们学习Java的IO流之前,我们都要了解几个关键词 同步与异步(synchronou ...

  2. IO NIO AIO及常用框架概述

    概述 nio 同步: 自己亲自出马持银行卡到银行取钱(使用同步IO时,Java自己处理IO读写). 异步: 委托一小弟拿银行卡到银行取钱,然后给你(使用异步IO时,Java将IO读写委托给OS处理,需 ...

  3. 3. 彤哥说netty系列之Java BIO NIO AIO进化史

    你好,我是彤哥,本篇是netty系列的第三篇. 欢迎来我的公从号彤哥读源码系统地学习源码&架构的知识. 简介 上一章我们介绍了IO的五种模型,实际上Java只支持其中的三种,即BIO/NIO/ ...

  4. java IO NIO BIO 最权威的总结

    1. BIO (Blocking I/O) 1.1 传统 BIO 1.2 伪异步 IO 1.3 代码示例 1.4 总结 2. NIO (New I/O) 2.1 NIO 简介 2.2 NIO的特性/N ...

  5. JAVA bio nio aio

    [转自]http://qindongliang.iteye.com/blog/2018539 在高性能的IO体系设计中,有几个名词概念常常会使我们感到迷惑不解.具体如下: 序号 问题 1 什么是同步? ...

  6. java BIO/NIO/AIO 学习

    一.了解Unix网络编程5种I/O模型 1.1.阻塞式I/O模型 阻塞I/O(blocking I/O)模型,进程调用recvfrom,其系统调用直到数据报到达且被拷贝到应用进程的缓冲区中或者发生错误 ...

  7. Java IO/NIO教程

    Java IO教程 http://tutorials.jenkov.com/java-io/index.html Java NIO教程 英文版: http://tutorials.jenkov.com ...

  8. Java IO NIO详细讲解

    1.IO Java IO概述 2.NIO Java NIO浅析

  9. JAVA的 IO NIO AIO笔记

        IO      linux内核将所有外部设备都看做一个文件来操作,对一个文件的读写会调用内核系统命令,放回一个file descriptor(文件描述符), 对一个socket的读写也会有相应 ...

  10. Java之io nio aio 的区别

    这个问题最近面试总是遇到,作为一个只会写流水代码的程序员,一脸懵逼.看了网上的解释,看的还是很模糊,说下我对这个的理解. 先引出一个话题,两个大水缸,一个空一个满,让你把一个缸里面的水弄到另一个里面. ...

随机推荐

  1. pycharm2018.11最新激活码

    第一步:先按下键盘的win + r ,然后复制c:\windows\system32\drivers\etc粘贴到对话框回车打开文件管理器: 第二步:打开hosts文件,将0.0.0.0 accoun ...

  2. Linux基础入门-环境变量与文件查找

    一.环境变量: Shell中的变量也有不同的数据类型,不用专门指定类型名,可以参与运算,有作用域限制. declare tmp 创建一个变量 可以不用专门声明,可以即用即创建 tmp=shiyanlo ...

  3. github的markdown页内锚点以及本地资源链接

    页内锚点参考 https://my.oschina.net/antsky/blog/1475173 [aaa](#2-aaabbb) 字母小写,.去掉,空格换成- 本地资源链接 [aaa](docs/ ...

  4. pycrypto安装出错的问题 intmax_t C:\Program Files (x86)\Windows Kits\10\include\10.0.10240.0\ucrt\inttypes.

    前言: 需要安装 Microsoft Visual Studio2017 Community 或者buildtools 解决方案一(解决了python3.7上安装pycrypto-2.6.1的错误问题 ...

  5. docker18.09.5 Dockerfile文件编写

    Dockerfile命令详解(超全版本)  https://www.cnblogs.com/dazhoushuoceshi/p/7066041.html 案例1 dockerfile文件内容: FRO ...

  6. nginx1.14.0版本location路径配置四种方式

    假设下面四种情况分别用 http://192.168.1.1/proxy/test.html 进行访问. 第一种:location /proxy/ {    proxy_pass http:// 12 ...

  7. Zabbix调优不完全指南(https://www.jianshu.com/p/2d911d55448f)

    从学习搭建zabbix到完成各类监控.调优.二次开发已经过去了两年,期间通过QQ学习群.zabbix官方社区.各个技术博客整理学习了不少关于各种报错的处理方法,现在将常见的一些报错处理方法整理出来分享 ...

  8. airflow整体架构

    run命令运行过程 读取dag文件生成task依赖关系,然后生成封装airflow run的command命令,通过celery发送到executor端,重新执行该airflow run命令. sch ...

  9. 学习MeteoInfo二次开发教程(十二)

    1.添加新的Form窗体: 在解决方案资源管理器中,右键MeteoInfoDemo,“添加”,“Windows 窗体” 2.新窗体中添加好layersLegend1和Layout之后,要把layers ...

  10. 如何在vue+element中实现选择框和穿梭框的根据拼音以及拼音首字母以及汉字的模糊搜索

    1.汉字: 直接添加对应的 filterable     2.拼音: 穿梭框和选择器的实现方式有所不同   选择器:   <1>下载pinyin-match:   npm i --save ...