关于数据流

=====

在数据输入输出描述中,我们抽象出了一个概念叫做流Stream, 简单数来就是从一个点到另外一个点的数据有序流动,或者说是一个任意长度的有序字节序列。

在Java编程中,我们为了更好的管理数据流动,将流分为输入流和输出流,并抽象了两个接口定义InputStream和OutputStream来分别描述它们。

因为我们计算机底层对于数据处理的基本单位是字节byte,所以我们数据流的基本单元也是比特,我们也称这样的数据流为字节流。

每个数据流都有两个端点,分别为数据源和数据目的地。通常它们可以是文件,网络数据流等。

很多小伙伴在学习Java编程时,很容易被I/O这部分的一些列概念定义搞混了。因为所有的数据流都是以字节流为基础根据各类数据类型的定义进行的编码处理后的结果。

在理解Java的I/O类型时,需要先了解一个设计模式,那就是装饰器模式。

简单来说,装饰器模式是通过一个基础的接口来描述所有接口约定,然后用基础实现类和附加实现类结合共同实现该接口,如此一来我们就可以保留原有接口实现的功能,并且能够通过实现类来提供附加处理功能,并提供统一的对外接口。

Java的输入输出流类型定义就遵循的这一模式,数据流的基础实现ByteInputStream和ByteOutputStream作为基础类,增加了继承继承接口的过滤功能接口和缓冲功能接口,通过它们的实现类我们可以对本来只能处理单个字节的数据流类变为可以通过特定缓冲区来缓存一定数量的字节后进行处理的BufferStream以及缓存后对整体数据添加条件过滤的BufferFilterStream。

进而我们根据各种数据类型的编码规则,对基础的字节流进行编解码处理,定义出了字符,整型,长整型,浮点型等能够处理各基础类型的数据流类型定义。

标准 输入输出

=======

许多操作系统都支持这种标准输入/输出,它是在开始执行时,计算机程序和它运行环境之间预先连接的输入输出流。

这种预连接的流通常有标准输入,标准输出和标准错误流。

最常见的实现了编解码功能的就是我们常说的标准流,Java编程中我们从java.system中能够看到in,out,err等标准I/O流的定义。

标准输入默认从键盘读取它的输入。

标准输出和标准错误默认将它们的输出到屏幕上。

数据流的分类

======

说到数据流就不得不说我们常见的数据流类型,通常我们处理的数据主要分为两种类型,一种是基于文件存储块的块类型数据流,另一种是基于网络字节流的流类型数据流。

而我们编写的几乎所有的应用程序都会或多或少的涉及到这两种类似数据流的处理,当然也有极少数特殊的应用程序不需要我们操作数据流。

我们知道计算机操作系统中是以文件系统作为数据存储和操作的基础组件的,文件系统设计是基于数据存储的物理磁盘结构来设计的,因为磁盘是以固定的分区块来管理数据存取的。

所以基于文件的数据流都是面向块操作的数据流,而像基于网络访问的数据流动则是面向字节流的数据流。

很明显面向块的数据流处理要比面向流的数据处理要快速。

关于NIO模型

=======

前面讲到Java开发最初对于I/O的支持模式是单线路的,也就是说需要CPU全程参与数据读取过程。每个数据输入或者输出的处理线程都需要CPU来阻塞执行。即一旦开始读写,CPU将等待其结束,然后才能进行其它任务执行。

随着技术的发展,NIO模型的出现,该模型巧妙的设计了一个内存缓冲区和通道概念,将原来针对具体数据流的操作,封装成了对于缓冲区的操作。并将所有操作都抽象到一个通道模型里。

其中引入的缓冲区概念Buffer是新一代输入输出操作模型的基础,它本质上是一块内存空间的抽象,并将其具体的操作指令化封装给连接到它的通道Channel上。

由通道来封装跟这内存区域关联的数据源或者目的地。通道的read()和write()方法来触发CPU对读写事件的响应处理。

具体就是在read()指令发出后,操作系统会将数据从数据源读入到指定的缓冲区里,而当write()指令发出后,则会将连接到该通道的缓冲区数据排空出缓冲区到指定的数据目的地。

如此我们就不难理解,我们可以将基于任意数据源建立的流封装成对应的数据通道,然后为通道指定连接的缓冲区,接下来就是发送相关指令来进行目标数据的操作了。

我们使用Java编写的所有应用程序都是受到JVM进程管理的,所以跟操作系统的通信也是有JVM负责完成的。

JVM在执行I/O时,通过请求操作系统执行一个write操作排空缓冲区内容到存储器,使用一个读操作来从存储设备读取数据填充缓冲区空间。

假设我们的读操作包含一个硬盘驱动步骤,操作系统会发布一个命令给硬盘控制器来从硬盘上读取一个字节块到操作系统的缓冲区。

一旦这一操作完成,操作系统会拷贝其缓冲区的内容到由我们发起的read()操作的进程指定的缓冲区里。

如果我们的应用程序进程发布一个read()方法调用操作系统,那么操作系统会请求硬盘控制器来从硬盘上读取数据字节块。

DMA技术问题

=======

这里硬盘控制器就是通过前面提到的直接内存访问技术(DMA)来将数据从硬盘读取到操作系统的缓冲区里。

因为DMA能够允许特定的硬件子系统独立于CPU而直接访问主系统内存。

其实,这种从操作系统缓冲区拷贝字节到应用程序进程缓冲区并不是一个高效的方式。

如果让DMA控制器直接将数据拷贝到进程缓冲区会更高效,但是我们在用它编程过程中会遇到两个问题:

DMA控制器通常不能直接跟运行JVM进程的用户空间进行交互,它只能跟操作系统的内核空间交互。

一般面向块存储的设备,其操作的数据块是固定大小的,而我们应用程序的JVM进程可能需要的数据类型大小不一定就是存储块的倍数,这就会出现数据流类型的错配。

所以,必须在直接访问控制器的数据与具体应用程序的数据之间有一个适配过程,

【一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义】浏览器打开:qq.cn.hn/FTf 免费领取

而这个过程就是由我们的操作系统来执行的。

通常我们的操作系统会在JVM进程和DMA控制器之间数据转换时对数据进行分解和重组,使得它们之间能够顺畅的通信。

NIO三要素:缓冲器,通道,就绪选择器

IO输入输出模型是每个Java开发人员必须理解的重点,深度解析跳槽从开始到结束完整流程相关推荐

  1. 基于安卓的兼职app开发!深度解析跳槽从开始到结束完整流程,分享PDF高清版

    开头 最近有粉丝反应,不想做安卓了,有朋友转到前端了,安卓不行了,问我怎么办? 自从RN,Weex这种跨平台编程语言出来以后,安卓将死的言论总是不绝于耳.随着颇有摧枯拉朽之势Flutter的出现,加之 ...

  2. Java面试题!深度解析跳槽从开始到结束完整流程,吊打面试官

    一.Spring Cloud微服务概念定义 提起微服务,不得不提 Spring Cloud 全家桶系列,Spring Cloud 是一个服务治理平台,是若干个框架的集合,提供了全套的分布式系统解决方案 ...

  3. Java开发人员如何构建自己的技术体系

    Java是现阶段中国互联网公司中,覆盖度最广的研发语言,掌握了Java技术体系,不管在成熟的大公司,快速发展的公司,还是创业阶段的公司,都能有立足之地.成为Java架构师除了掌握Java语法之外,还要 ...

  4. java开发错误_每个Java开发人员都必须避免的9个安全错误

    java开发错误 Checkmarx CxSAST是功能强大的源代码分析(SCA)解决方案,旨在从根本上识别,跟踪和修复技术和逻辑安全漏洞:源代码. 在这里查看 ! 自从1995年中期引入Java以来 ...

  5. 每个Java开发人员都必须避免的9个安全错误

    Checkmarx CxSAST是功能强大的源代码分析(SCA)解决方案,旨在从根本上识别,跟踪和修复技术和逻辑安全缺陷:源代码. 在这里查看 ! 自从1995年中期引入Java以来​​,它已经走了很 ...

  6. Java自己文章只能自己修改_文章目录Java代码俯身指南,主要为Java开发人员提供代码复审参考,快捷有效提出修改意见。目的发现代码错误:一个人写的代码可能会有一些思想和设计盲点,多个人尽...

    文章目录 Java代码俯身指南,主要为Java开发人员提供代码复审参考,快捷有效提出修改意见. 目的发现代码错误:一个人写的代码可能会有一些思想和设计盲点,多个人尽早的发现BUG. 统一代码风格:统一 ...

  7. 适用于Java开发人员的微服务:管理安全性和机密

    关于麦洛 麦洛是 Java 开发者和技术爱好者. 对 Java 相关技术特别感兴趣,包括 javaee. Spring系列. 微服务等 作者:Andrey Redko 原文:Microservices ...

  8. 面向 Java 开发人员的 Ajax: 构建动态的 Java 应用程序

    面向 Java 开发人员的 Ajax: 构建动态的 Java 应用程序 Ajax 为更好的 Web 应用程序铺平了道路 在 Web 应用程序开发中,页面重载循环是最大的一个使用障碍,对于 Java™ ...

  9. 面向 Java 开发人员的 Scala 指南: 深入了解 Scala 并发性

    http://www.ibm.com/developerworks/cn/java/j-scala04109.html http://www.ibm.com/developerworks/cn/jav ...

最新文章

  1. 如果三十年前有这些AI技术,可可西里的悲剧不会发生
  2. linux源码阅读笔记 fork函数
  3. 两台linux之间实现共享文件夹挂载实例,linux之间实现共享文件夹挂载实力
  4. Web开发中的用户角色权限设计总结
  5. go语言mysql操作_使用Go语言操作MySQL数据库的思路与步骤
  6. 这家总资产排名第一的银行,为什么叫“小”摩?
  7. Lesson 07 for Plotting in R for Biologists
  8. nginx IP 443 路由到其它地址
  9. Microsoft word 表格居中对齐方法
  10. adb shell 出现 error :
  11. 离线下载谷歌浏览器chrome安装包
  12. 官方文档-Linux服务器集群系统(一)
  13. 思念绵绵,爱在彼此心间漫延
  14. 读取数据快慢的设备_目前在以下各种设备中,读取数据快慢的顺序是内存、硬盘、光盘和软盘。...
  15. java解析eml文件_使用JavaMail解析EML文件详解
  16. Python中的乘方计算
  17. Linux下如何安装Firefox
  18. Gaussian Error Linerar Units(GELUS)激活函数详细解读
  19. mysql 实现 connect by start with
  20. 条码标签软件如何逆序批量打印序列号

热门文章

  1. 计算机 继续教育培训心得体会,继续教育学习心得体会范文(精选5篇)
  2. 小赢科技2020年一季报:由盈转亏1.96亿,M3以下贷款逾期率翻倍达6.71%
  3. Linux之NVIDIA显卡驱动安装方法(重启失效解决方法)
  4. 用java编写连连看_用java语言编写连连看游戏
  5. 如何在三维模型中按一定密度提取点云数据(详细说明)
  6. 算法设计与分析实验指导(完整版)
  7. android MediaPlayer架构
  8. (转载)Nim游戏博弈(收集完全版)
  9. RabbitMQ的简单使用
  10. VPO微珀宣布完成千万人民币Pre-A融资,专注电子烟场景化消费市场