NIO(1)

在这里插入图片描述
在这里插入图片描述面向流:向流数据进行操作。流是单向的。可以把流理解为水流,水流在管道中只能流向一个方向。

在这里插入图片描述
NIO:面向缓冲区
NIO 中的通道:可以把它理解为铁路,铁路(通道)本身并没有传输功能,它就是用来连接的,但可以通过火车(工具) 来进行数据的传输。这个火车(工具) 就叫缓冲区。而是是双向的,火车可以在轨道上两头走的。
通道:负责连接。
缓冲区:负责存储数据。
在这里插入图片描述在这里插入图片描述

第一个区别是针对于IO 与NIO 本身而言的。
第二第三个区别是针对于网络编程(Socket) 而言的
在这里插入图片描述

缓冲区:
在这里插入图片描述
在这里插入图片描述Buffer: 底层就是一个数组
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述put() : 写模式

在这里插入图片描述
filp(): 切换成读模式
在这里插入图片描述在这里插入图片描述在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
clear():
position 和limit 回到最初状态,无法知道buffer 中数据情况,所以就无法正确读取数据。
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述在这里插入图片描述

在这里插入图片描述remaining : limit - position
在这里插入图片描述

直接缓冲区与非直接缓冲区:
在这里插入图片描述

API 上的详细介绍:
在这里插入图片描述

当应用程序向磁盘空间发送IO 请求(read(), write()),不是直接通过应用程序直接把数据读/写到磁盘文件中的,而是通过一些过程:
内核地址空间:操作系统的内存空间
用户地址空间:JVM 的地址空间。
传统IO 操作 和通过allocate()分配的缓冲区都是用的非直接缓冲区。
在这里插入图片描述
其实中间的copy 操作是没有必要的,所以NIO 中就直接在物理内存中开辟Buffer 内存空间,应用程序和物理磁盘直接面向这个Buffer 来进行读/写数据。
所以NIO 的效率比传统IO 的效率要高。因为省去了copy 操作。
弊端:1.不安全 2. 因为缓冲区直接建立到物理内存中,所以是比JVM 上建立Buufer消耗大,销毁的消耗也大。 3. 当数据写到物理内存映射文件(Buffer)中时,数据什么时候到达目的地(物理磁盘/ 应用程序),是由操作系统说了算,所以这里数据不易控制。
如果数据能长时间在内存进行操作,或者大量大数据不想在JVM 中开辟空间,就可以放到这个物理内存映射文件中。
这个物理内存什么时候释放? 当GC 回收的时候,回收到应用程序对这个物理内存的引用时,这是这个物理内存才会被回收。
在这里插入图片描述
从源码角度看直接缓冲区和非直接缓冲区的区别:

在这里插入图片描述非直接缓冲区底层就是一个分配在堆空间的数组。
在这里插入图片描述
直接缓冲区分配方法:
在这里插入图片描述
点进去是看不了的了。
在这里插入图片描述使用API 判断是不是直接缓冲区。
在这里插入图片描述

通道:
源节点和目标节点的连接
在这里插入图片描述

当我们发起读写请求时,CPU 会把目标物理磁盘中的数据,拿到内存中进行运算。
最早期的IO 接口,全都是由CPU 独立负责的,当我们应用程序发起读写请求时,CPU 的占用率就变得很高。以至于CPU 不能做其他工作。没有高效的利用CPU。
在这里插入图片描述后来做了改良:在内存和IO 接口之间搞了一个DMA(直接存储器)。这是当应用系统对操作系统发送读写请求时,DMA 会向CPU 申请权限(资源),CPU 给了它权限以后,IO 接口的操(读写操作)作就全权由DMA 来负责操作。这样CPU 就能有更多资源去执行其他工作。
传统的数据传输方式:DMA(就是我们所说的IO 流)
如果应用程序发起大量的读写请求时,DMA 会不断的向CPU 申请资源,然后不断的建立DMA 总线,如果DMA 总线过多,会造成总线冲突问题。如果出现这个问题,也会影响性能。
在这里插入图片描述
继续改良:
把DMA 改良成通道的方式(DMA 还是存在的)。通道的好处:它是一个完全独立的处理器,专门用于IO 操作的,有自己的命令。(它依然附属于CPU)这样就和CPU 直接分开了,当进行IO 操作时不需要向CPU 申请资源。
其实通道和DMA 处理IO 请求的方式是差不多的,但是对于大量的IO 读写操作来说,因为通道独立于CPU,而DMA 仍需向CPU 申请资源,所以此时的效率通道会高一点。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
实例:
1.利用通道完成文件的复制(非直接缓冲区)
通过流的方式来获取通道,很少用到,只是体现了流对通道的支持
在这里插入图片描述I/O 操作完不要忘记关闭流
在这里插入图片描述在这里插入图片描述
因为流本来就具有读写功能,所以对应的通道具有读写功能,但这也是非直接内存中的Buffer 才有的功能。
直接内存中的通道不具备读写数据功能,只能通过Buffer 来进行数据读写
2.使用直接缓冲区完成文件的复制(物理内存映射文件)

先建立目标通道:获取数据的通道跟传输数据的通道
Paths: 目标通道的路径。可以用拼串的形式把路径分开写。
StandardOpenOption:可以对通道进行权限控制,作用就是:当Buffer 对通道进行操作的时候,如果权限不符合,就会直接报错。

比如传输数据的通道,有两个个权限:CREATE ,CREATE_NEW 。CREATE :当Paths 路径下有相同名字的文件,就再创建一个相同名字的文件。CREATE_NEW :当Paths 路径下有相同名字的文件,会直接报错
在这里插入图片描述
通道打开,并且授予对应的权限以后,开始创建对应通道的内存映射文件(这个内存映射文件就是直接字节缓冲区。这个缓冲区在物理内存中。而且这个缓冲区只有ByteBuffer)。
注意! 通道的内存映射文件权限一定要和对应通道的权限一样,不然会报错。比如outMappedBuf 内存映射文件权限是read_write。它对应的通道的权限只是write。所以这样运行会报错。
在这里插入图片描述
在这里插入图片描述修改通道权限:
在这里插入图片描述
一个通道对应一个字节缓冲区,那么在复制文件的时候需要用到一个中间的字节数据在作为中间载具。把读取通道中的缓冲区(inMappedBuf)的数据写到字节数据中,在把字节数组中的数据写到写通道(outMappedBuf)的缓冲区中。
在这里插入图片描述

整体代码:
在这里插入图片描述
从直接内存中进行读写操作是比非直接内存中进行读写操作快很多的,但同时也有问题:

文件已经读写完了,程序还没运行完(虽然是绿色,但还是没运行完,我们的时间还没打印),同时CPU 占用率还很高。
在这里插入图片描述
正常结束是这样的:
在这里插入图片描述
也就是说文件已经读写完毕了,但程序不仅没那么快结束,就是JVM一直引用着物理内存的那个缓冲区(也就是垃圾回收机制没有及时释放掉对直接内存的引用),导CPU 占用率一下过高。
总结:操作直接内存缓冲区,效率虽高,但并不是所有的时候都很稳定(占用CPU)。原因就是:当我们把数据从程序写到物理内存的映射文件(缓冲区)时,这时候这些数据就不归程序管了。什么时候把数据写到磁盘,就是操作系统的事了。跟我们写的程序无关。所以如果垃圾回收机制不及时释放掉对物理内存的内存文件的引用,程序还无法停下来。
建议:如果你希望你的缓冲区存放的时间长,那就存放在物理内存中。
在这里插入图片描述
通道之间的数据传输:
在这里插入图片描述
在这里插入图片描述
下面这种和上面得到的效果都是一样的。只是通道之间的数据传输方向:To, From 的区别而已。都能实现对文件的复制。
在这里插入图片描述目前还都是I/O 和NIO 的区别,还没有涉及网络编程。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用 JavaScript 编写的记忆游戏(附源代码)   项目:JavaScript 记忆游戏(附源代码) 记忆检查游戏是一个使用 HTML5、CSS 和 JavaScript 开发的简单项目。这个游戏是关于测试你的短期 记忆技能。玩这个游戏 时,一系列图像会出现在一个盒子形状的区域中 。玩家必须找到两个相同的图像并单击它们以使它们消失。 如何运行游戏? 记忆游戏项目仅包含 HTML、CSS 和 JavaScript。谈到此游戏的功能,用户必须单击两个相同的图像才能使它们消失。 点击卡片或按下键盘键,通过 2 乘 2 旋转来重建鸟儿对,并发现隐藏在下面的图像! 如果翻开的牌面相同(一对),您就赢了,并且该对牌将从游戏中消失! 否则,卡片会自动翻面朝下,您需要重新尝试! 该游戏包含大量的 javascript 以确保游戏正常运行。 如何运行该项目? 要运行此游戏,您不需要任何类型的本地服务器,但需要浏览器。我们建议您使用现代浏览器,如 Google Chrome 和 Mozilla Firefox, 以获得更好、更优化的游戏体验。要玩游戏,首先,通过单击 memorygame-index.html 文件在浏览器中打开游戏。 演示: 该项目为国外大神项目,可以作为毕业设计的项目,也可以作为大作业项目,不用担心代码重复,设计重复等,如果需要对项目进行修改,需要具备一定基础知识。 注意:如果装有360等杀毒软件,可能会出现误报的情况,源码本身并无病毒,使用源码时可以关闭360,或者添加信任。
使用 JavaScript 编写的 Squareshooter 游戏及其源代码   项目:使用 JavaScript 编写的 Squareshooter 游戏(附源代码) 这款游戏是双人游戏。这是一款使用 JavaScript 编写的射击游戏,带有门户和强化道具。在这里,每个玩家都必须控制方形盒子(作为射手)。这款射击游戏的主要目标是射击对手玩家以求生存。当它射击对手时,它会获得一分。 游戏制作 该游戏仅使用 HTML 和 JavaScript 开发。该游戏的 PC 控制也很简单。 对于玩家 1: T:朝你上次动作的方向射击 A:向左移动 D:向右移动 W:向上移动 S:向下移动 对于玩家2: L:朝你上次移动的方向射击 左箭头:向左移动 右箭头:向右移动 向上箭头:向上移动 向下箭头:向下移动 游戏会一直进行,直到您成功射击对手或对手射击您为止。游戏得分显示在顶部。所有游戏功能均由 JavaScript 设置,而布局和其他次要功能则由 HTML 设置。 如何运行该项目? 要运行此项目,您不需要任何类型的本地服务器,但需要浏览器。我们建议您使用现代浏览器,如 Google Chrome 和 Mozilla Firefox。要运行此游戏,首先,通过单击 index.html 文件在浏览器中打开项目。 演示: 该项目为国外大神项目,可以作为毕业设计的项目,也可以作为大作业项目,不用担心代码重复,设计重复等,如果需要对项目进行修改,需要具备一定基础知识。 注意:如果装有360等杀毒软件,可能会出现误报的情况,源码本身并无病毒,使用源码时可以关闭360,或者添加信任。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值