IO

什么是IO? 它是指计算机与外部世界或者一个程序与计算机的其余部分的之间的接口。它对于任何计算机系统都非常关键,因而所有 I/O 的主体实际上是内置在操作系统中的。单独的程序一般是让系统为它们完成大部分的工作。

在 Java 编程中,直到最近一直使用 流 的方式完成 I/O。所有 I/O 都被视为单个的字节的移动,通过一个称为 Stream 的对象一次移动一个字节。流 I/O 用于与外部世界接触。它也在内部使用,用于将对象转换为字节,然后再转换回对象。

BIO

Java BIO即Block I/O , 同步并阻塞的IO。

BIO就是传统的java.io包下面的代码实现。

NIO

什么是NIO? NIO 与原来的 I/O 有同样的作用和目的, 他们之间最重要的区别是数据打包和传输的方式。原来的 I/O 以流的方式处理数据,而 NIO 以块的方式处理数据。

面向流 的 I/O 系统一次一个字节地处理数据。一个输入流产生一个字节的数据,一个输出流消费一个字节的数据。为流式数据创建过滤器非常容易。链接几个过滤器,以便每个过滤器只负责单个复杂处理机制的一部分,这样也是相对简单的。不利的一面是,面向流的 I/O 通常相当慢。

一个 面向块 的 I/O 系统以块的形式处理数据。每一个操作都在一步中产生或者消费一个数据块。按块处理数据比按(流式的)字节处理数据要快得多。但是面向块的 I/O 缺少一些面向流的 I/O 所具有的优雅性和简单性。

AIO

Java AIO即Async非阻塞,是异步非阻塞的IO。

区别及联系
BIO (Blocking I/O):同步阻塞I/O模式,数据的读取写入必须阻塞在一个线程内等待其完成。这里假设一个烧开水的场景,有一排水壶在烧开水,BIO的工作模式就是, 叫一个线程停留在一个水壶那,直到这个水壶烧开,才去处理下一个水壶。但是实际上线程在等待水壶烧开的时间段什么都没有做。

NIO (New I/O):

同时支持阻塞与非阻塞模式,但这里我们以其同步非阻塞I/O模式来说明,那么什么叫做同步非阻塞?如果还拿烧开水来说,NIO的做法是叫一个线程不断的轮询每个水壶的状态,看看是否有水壶的状态发生了改变,从而进行下一步的操作。

AIO ( Asynchronous I/O):

异步非阻塞I/O模型。异步非阻塞与同步非阻塞的区别在哪里?异步非阻塞无需一个线程去轮询所有IO操作的状态改变,在相应的状态改变后,系统会通知对应的线程来处理。对应到烧开水中就是,为每个水壶上面装了一个开关,水烧开之后,水壶会自动通知我水烧开了。

各自适用场景

BIO方式适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中,JDK1.4以前的唯一选择,但程序直观简单易理解。

NIO方式适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,并发局限于应用中,编程比较复杂,JDK1.4开始支持。

AIO方式适用于连接数目多且连接比较长(重操作)的架构,比如相册服务器,充分调用OS参与并发操作,编程比较复杂,JDK7开始支持。

使用方式

使用BIO实现文件的读取和写入。

   //Initializes The ObjectUser1 user = new User1();user.setName("hollis");user.setAge(23);System.out.println(user);//Write Obj to FileObjectOutputStream oos = null;try {oos = new ObjectOutputStream(new FileOutputStream("tempFile"));oos.writeObject(user);} catch (IOException e) {e.printStackTrace();} finally {IOUtils.closeQuietly(oos);}//Read Obj from FileFile file = new File("tempFile");ObjectInputStream ois = null;try {ois = new ObjectInputStream(new FileInputStream(file));User1 newUser = (User1) ois.readObject();System.out.println(newUser);} catch (IOException e) {e.printStackTrace();} catch (ClassNotFoundException e) {e.printStackTrace();} finally {IOUtils.closeQuietly(ois);try {FileUtils.forceDelete(file);} catch (IOException e) {e.printStackTrace();}}//Initializes The ObjectUser1 user = new User1();user.setName("hollis");user.setAge(23);System.out.println(user);//Write Obj to FileObjectOutputStream oos = null;try {oos = new ObjectOutputStream(new FileOutputStream("tempFile"));oos.writeObject(user);} catch (IOException e) {e.printStackTrace();} finally {IOUtils.closeQuietly(oos);}//Read Obj from FileFile file = new File("tempFile");ObjectInputStream ois = null;try {ois = new ObjectInputStream(new FileInputStream(file));User1 newUser = (User1) ois.readObject();System.out.println(newUser);} catch (IOException e) {e.printStackTrace();} catch (ClassNotFoundException e) {e.printStackTrace();} finally {IOUtils.closeQuietly(ois);try {FileUtils.forceDelete(file);} catch (IOException e) {e.printStackTrace();}}

使用NIO实现文件的读取和写入。


static void readNIO() {String pathname = "C:\\Users\\adew\\Desktop\\jd-gui.cfg";FileInputStream fin = null;try {fin = new FileInputStream(new File(pathname));FileChannel channel = fin.getChannel();int capacity = 100;// 字节ByteBuffer bf = ByteBuffer.allocate(capacity);System.out.println("限制是:" + bf.limit() + "容量是:" + bf.capacity()+ "位置是:" + bf.position());int length = -1;while ((length = channel.read(bf)) != -1) {/** 注意,读取后,将位置置为0,将limit置为容量, 以备下次读入到字节缓冲中,从0开始存储*/bf.clear();byte[] bytes = bf.array();System.out.write(bytes, 0, length);System.out.println();System.out.println("限制是:" + bf.limit() + "容量是:" + bf.capacity()+ "位置是:" + bf.position());}channel.close();} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {if (fin != null) {try {fin.close();} catch (IOException e) {e.printStackTrace();}}}}static void writeNIO() {String filename = "out.txt";FileOutputStream fos = null;try {fos = new FileOutputStream(new File(filename));FileChannel channel = fos.getChannel();ByteBuffer src = Charset.forName("utf8").encode("你好你好你好你好你好");// 字节缓冲的容量和limit会随着数据长度变化,不是固定不变的System.out.println("初始化容量和limit:" + src.capacity() + ","+ src.limit());int length = 0;while ((length = channel.write(src)) != 0) {/** 注意,这里不需要clear,将缓冲中的数据写入到通道中后 第二次接着上一次的顺序往下读*/System.out.println("写入长度:" + length);}} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {if (fos != null) {try {fos.close();} catch (IOException e) {e.printStackTrace();}}}}

使用AIO实现文件的读取和写入

public class ReadFromFile {public static void main(String[] args) throws Exception {Path file = Paths.get("/usr/a.txt");AsynchronousFileChannel channel = AsynchronousFileChannel.open(file);ByteBuffer buffer = ByteBuffer.allocate(100_000);Future<Integer> result = channel.read(buffer, 0);while (!result.isDone()) {ProfitCalculator.calculateTax();}Integer bytesRead = result.get();System.out.println("Bytes read [" + bytesRead + "]");}
}
class ProfitCalculator {public ProfitCalculator() {}public static void calculateTax() {}
}public class WriteToFile {public static void main(String[] args) throws Exception {AsynchronousFileChannel fileChannel = AsynchronousFileChannel.open(Paths.get("/asynchronous.txt"), StandardOpenOption.READ,StandardOpenOption.WRITE, StandardOpenOption.CREATE);CompletionHandler<Integer, Object> handler = new CompletionHandler<Integer, Object>() {@Overridepublic void completed(Integer result, Object attachment) {System.out.println("Attachment: " + attachment + " " + result+ " bytes written");System.out.println("CompletionHandler Thread ID: "+ Thread.currentThread().getId());}@Overridepublic void failed(Throwable e, Object attachment) {System.err.println("Attachment: " + attachment + " failed with:");e.printStackTrace();}};System.out.println("Main Thread ID: " + Thread.currentThread().getId());fileChannel.write(ByteBuffer.wrap("Sample".getBytes()), 0, "First Write",handler);fileChannel.write(ByteBuffer.wrap("Box".getBytes()), 0, "Second Write",handler);}
}

浅谈IO及不同的理解相关推荐

  1. 浅谈 我对 技术 的理解

    文章目录 1.浅谈 我对 技术 的理解 1.1 技术 是 什么? 1.2 技术的 两个 核心 构成 要素 1.2.1 知识 层面 1.2.2 智慧 层面(思考 层面) 1.3 技术 很难?学不明白? ...

  2. 浅谈对seo概念的理解

    个人认为与微信一样,搜索引擎有固定的用户群体,有人有流量的地方,就存在商机或者利益,seo的概念就是搜索引擎优化,其目的是在搜索引擎中获得精准用户,获得流量.从更深层次方面看,利用seo做自然排名获得 ...

  3. 浅谈阿里“中台”概念的理解

    https://www.toutiao.com/a6651015208934310414/?tt_from=mobile_qq&utm_campaign=client_share&ti ...

  4. 浅谈我对JCS 的理解

    JCS 是Java 中缓存的一种实现,支持将数据缓存到内存和硬盘中,支持设置缓存对象的有效时长. 我认为可以这么理解JCS:客户端向服务器发出请求,服务器就先去缓存中查一下有没有客户端请求的数据,有则 ...

  5. 浅谈数据库三大范式的理解

    首先声明一下,我的这个回答是个人工作总结,不适合考试答题昂. 欢迎关注我的博客. 前言:数据库设计其实不仅仅限制于三个范式,往下其实还有很多种,但对于大多数人来说,你又不搞科研,不造飞机大炮,掌握三大 ...

  6. java io流_浅谈IO流(一)-流的基本概念以及java的常见流

    对于任何程序设计语言而言,输入输出(Input/Output)系统都是非常核心的功能.程序运行需要数据,数据的获取往往需要跟外部系统进行通信,外部系统可能是文件.数据库.其他程序.网络.IO设备等等. ...

  7. 浅谈对js闭包的理解

    闭包就是能够读取其他函数内部变量的函数.由于在javascript中,只有函数内部的子函数才能读取局部变量,所以闭包可以理解成"定义在一个函数内部的函数".在本质上,闭包是将函数内 ...

  8. 【Docker】Docker镜像是什么?浅谈对Docker镜像的理解

    专栏往期文章 <Docker是什么?Docker从介绍到Linux安装图文详细教程> <30条Docker常用命令图文举例总结> 本期目录 专栏往期文章 1. Docker镜像 ...

  9. 【代码注释】浅谈对于代码注释的理解

    楔子:"这里的山路十八弯,这里的水路九连环":智慧的古人就懂得,通过把山路修成九曲十八弯来战胜陡峭的高坡.看则舍近求远绕圈而行,实为拿路程换高度,为完成登顶而蓄势待发.这种螺旋上升 ...

最新文章

  1. linux系统下网卡故障解决
  2. php单屏网站源码,关于原生js实现类似fullpage的单页/全屏滚动的方法
  3. Linux SKB结构体中各个长度字段的含义(len, data_len, headlen, pagelen)
  4. Android -- 自定义StepView实现个人信息验证进度条
  5. antd的table进行列筛选时,更新dataSource,为什么table显示暂无数据?
  6. 百练 05 切割回文
  7. POJ 3576 Language Recognition
  8. iOS开发日记29-UIAlertController
  9. 2022中山大学计算机技术专硕考研初试、复试经验帖
  10. Python教学视频(三)数据类型及类型间的转换
  11. CanBus的数据帧的获取和初始解析
  12. 关于listview的全选、反选、取消、删除等操作
  13. 【汇编实战开发笔记】80x86汇编基础的三大块知识
  14. 优化 | 线性化:0-1变量乘以连续变量的线性化
  15. [ctf.show.reverse] 数学不及格
  16. 21张手机壁纸,送给我爱的你们~
  17. DevOps元素周期表——1号元素 Gitlab
  18. 卡西欧计算机显示科学计数法怎么调回来,卡西欧计算器中的科学计数法键如何使用?请举例!急!...
  19. python 3.8+vscode 无法启动jupyter kernal问题
  20. 网站文化风格与网页设计

热门文章

  1. json数组 js html标签,js定义json对象数组 json 数组也是数组 //
  2. php 通过exec 创建git分支失败
  3. Python学习笔记__13.2章 requests
  4. shell 学习之正则、别名以及管道重定向
  5. HDU 6185 Covering 矩阵快速幂 递推
  6. struts2标签详解
  7. 进程间通信(三)—信号量
  8. 搭建一个免费的,无限流量的Blog----github Pages和Jekyll入门
  9. HDU 2444 The Accomodation of Students
  10. 什么是动态DNS 动态DNS有什么用