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

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

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

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

该文章浅谈了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也可以通过设置

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_Java IO、NIO、AIO知识总结相关推荐

  1. 关于java流的几个概念:IO、BIO、NIO、AIO,有几个人全知道?

    转载自 关于java流的几个概念:IO.BIO.NIO.AIO,有几个人全知道? 关于同步.阻塞的知识我之前的文章有介绍,所以关于流用到这些概念与之前多线程用的概念一样. 下面具体来看看java中的几 ...

  2. java 修改最大nio连接数_关于java流的几个概念:IO、BIO、NIO、AIO,有几个人全知道?...

    关于同步.阻塞的知识我之前的文章有介绍,所以关于流用到这些概念与之前多线程用的概念一样. 下面具体来看看java中的几种流 IO/BIO BIO就是指IO,即传统的Blocking IO,即同步并阻塞 ...

  3. java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之OS_Part_2整起~IO们那些事【包括五种IO模型:(BIO、NIO、IO多路复用、信号驱动、AIO);零拷贝、事件处理及并发等模型】

    PART0.前情提要: 通常用户进程的一个完整的IO分为两个阶段(IO有内存IO.网络IO和磁盘IO三种,通常我们说的IO指的是后两者!):[操作系统和驱动程序运行在内核空间,应用程序运行在用户空间, ...

  4. java中的三种IO(BIO、NIO、AIO)

    IO 阻塞和非阻塞主要指的是访问 IO 的线程是否会阻塞(或者说是等待) 线程访问资源,该资源是否准备就绪的一种处理方式 BIO(传统的IO) BIO是同步阻塞式的IO,以流的方式处理数据(效率低) ...

  5. 【IO】Java 中的 BIO、NIO、AIO

    在上一篇我们讲了 Linxu 下的五种 IO 模型,操作系统的 IO 模型是底层基石,Java对于IO的操作其实就是进一步的封装.适配一些系统调用方法,让我们玩地更得劲. 1.同步(Synchroni ...

  6. Java的IO流 ,BIO NIO AIO 的区别?

    目录 1.在了解不同的IO之前先了解:同步与异步,阻塞与非阻塞的区别: 2.BIO NIO AIO 分别代表什么?(面试简答): 3.BIO和NIO.AIO的区别: 4.java中io流的分类: •  ...

  7. java httputil_Java网络编程与NIO详解2:JAVA NIO 一步步构建IO多路复用的请求模型

    本文转载自:https://github.com/jasonGeng88/blog 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 http ...

  8. java mysql aio_Java中的NIO,BIO,AIO分别是什么

    Java中的NIO,BIO,AIO分别是什么 BIO:同步并阻塞,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开 ...

  9. Java NIO学习系列四:NIO和IO对比

    前面的一些文章中我总结了一些Java IO和NIO相关的主要知识点,也是管中窥豹,IO类库已经功能很强大了,但是Java 为什么又要引入NIO,这是我一直不是很清楚的?前面也只是简单提及了一下:因为性 ...

最新文章

  1. 中文分词的古今中外,你想知道的都在这里
  2. 【MFC】带进度条的状态栏
  3. for循环批量写文件 shell_shell脚本:for循环批量重命名带空格文件名的文件
  4. 476. 数字的补数
  5. Java关于md5+salt盐加密验证
  6. Nginx的Rewrite规则编写
  7. 高级软考之——系统分析师思维导图(一)
  8. 拍照怎么搜题?(上)
  9. 人工智能__一种现代方法 绪论导读
  10. AD19生成PCB_在Altium中导入Cadence Allegro的PCB文件
  11. 苹果录制屏幕在哪设置_屏幕录像专家如何录全屏 屏幕录像专家全屏录制设置方法...
  12. excel 导出PDF ExportAsFixedFormat函数 报错-2147024809 (0x80070057)
  13. 抖音短视频如何去水印
  14. html图片重叠轮播,HTML5--图片轮播多张展示
  15. 用慧编程做计算机,慧编程人工智能应用, 比个手势就能做算术!
  16. 编程技巧│使用 python 操作手机 app 超详细步骤
  17. Mysql基础篇(3)—— MySQL数据库类型
  18. 前端解决图片404的问题
  19. 分享六款原型设计软件,交流协作更便捷
  20. python json库安装_python-安装simplejson后没有名为“ json”的模块

热门文章

  1. centos7 卸载Qt5
  2. notepadpython插件_Notepad++插件Emmet和Python Script的安装
  3. celery java_Celery详解
  4. matlab 显示多幅图像,运用matlab实现循环语句中的多幅图像显示
  5. django html文本编辑器,django xadmin 集成DjangoUeditor富文本编辑器
  6. Android版本更新踩坑,Android Studio 3.0升级后踩到的坑
  7. php dingo和jwt,Laravel实现dingo+JWT api接口之配置篇
  8. js页面倒计时7天 java_javascript实现倒计时跳转页面
  9. nebula的nGQL语句可以为属性添加类似list的数字类型吗
  10. vim插件推荐之indentLine