NIO中的几个基础概念
一.NIO中的几个基础概念
在NIO中有几个比较关键的概念:Channel(通道),Buffer(缓冲区),Selector(选择器)。
首先从Channel说起吧,通道,顾名思义,就是通向什么的道路,为某个提供了渠道。在传统IO中,我们要读取一个文件中的内容,通常是像下面这样读取的:
public class Test {public static void main(String[] args) throws IOException {File file = new File("data.txt");InputStream inputStream = new FileInputStream(file);byte[] bytes = new byte[1024];inputStream.read(bytes);inputStream.close();}
}
这里的InputStream实际上就是为读取文件提供一个通道的。
因此可以将NIO 中的Channel同传统IO中的Stream来类比,但是要注意,传统IO中,Stream是单向的,比如InputStream只能进行读取操作,OutputStream只能进行写操作。而Channel是双向的,既可用来进行读操作,又可用来进行写操作。
Buffer(缓冲区),是NIO中非常重要的一个东西,在NIO中所有数据的读和写都离不开Buffer。比如上面的一段代码中,读取的数据时放在byte数组当中,而在NIO中,读取的数据只能放在Buffer中。同样地,写入数据也是先写入到Buffer中。
下面介绍一下NIO中最核心的一个东西:Selector。可以说它是NIO中最关键的一个部分,Selector的作用就是用来轮询每个注册的Channel,一旦发现Channel有注册的事件发生,便获取事件然后进行处理。
比如看下面的这个例子:
用单线程处理一个Selector,然后通过Selector.select()方法来获取到达事件,在获取了到达事件之后,就可以逐个地对这些事件进行响应处理。
二.Channel
在前面已经提到,Channel和传统IO中的Stream很相似。虽然很相似,但是有很大的区别,主要区别为:通道是双向的,通过一个Channel既可以进行读,也可以进行写;而Stream只能进行单向操作,通过一个Stream只能进行读或者写;
以下是常用的几种通道:
- FileChannel
- SocketChanel
- ServerSocketChannel
- DatagramChannel
通过使用FileChannel可以从文件读或者向文件写入数据;通过SocketChannel,以TCP来向网络连接的两端读写数据;通过ServerSocketChanel能够监听客户端发起的TCP连接,并为每个TCP连接创建一个新的SocketChannel来进行数据读写;通过DatagramChannel,以UDP协议来向网络连接的两端读写数据。
下面给出通过FileChannel来向文件中写入数据的一个例子:
public class Test {public static void main(String[] args) throws IOException {File file = new File("data.txt");FileOutputStream outputStream = new FileOutputStream(file);FileChannel channel = outputStream.getChannel();ByteBuffer buffer = ByteBuffer.allocate(1024);String string = "java nio";buffer.put(string.getBytes());buffer.flip(); //此处必须要调用buffer的flip方法channel.write(buffer);channel.close();outputStream.close();}
}
通过上面的程序会向工程目录下的data.txt文件写入字符串"java nio",注意在调用channel的write方法之前必须调用buffer的flip方法,否则无法正确写入内容,至于具体原因将在下篇博文中具体讲述Buffer的用法时阐述。
三.Buffer
Buffer,故名思意,缓冲区,实际上是一个容器,是一个连续数组。Channel提供从文件、网络读取数据的渠道,但是读取或写入的数据都必须经由Buffer。具体看下面这张图就理解了:
上面的图描述了从一个客户端向服务端发送数据,然后服务端接收数据的过程。客户端发送数据时,必须先将数据存入Buffer中,然后将Buffer中的内容写入通道。服务端这边接收数据必须通过Channel将数据读入到Buffer中,然后再从Buffer中取出数据来处理。
在NIO中,Buffer是一个顶层父类,它是一个抽象类,常用的Buffer的子类有:
- ByteBuffer
- IntBuffer
- CharBuffer
- LongBuffer
- DoubleBuffer
- FloatBuffer
- ShortBuffer
如果是对于文件读写,上面几种Buffer都可能会用到。但是对于网络读写来说,用的最多的是ByteBuffer。
关于Buffer的具体使用以及它的limit、posiion和capacity这几个属性的理解在下一篇文章中讲述。
四.Selector
Selector类是NIO的核心类,Selector能够检测多个注册的通道上是否有事件发生,如果有事件发生,便获取事件然后针对每个事件进行相应的响应处理。这样一来,只是用一个单线程就可以管理多个通道,也就是管理多个连接。这样使得只有在连接真正有读写事件发生时,才会调用函数来进行读写,就大大地减少了系统开销,并且不必为每个连接都创建一个线程,不用去维护多个线程,并且避免了多线程之间的上下文切换导致的开销。
与Selector有关的一个关键类是SelectionKey,一个SelectionKey表示一个到达的事件,这2个类构成了服务端处理业务的关键逻辑。
NIO中的几个基础概念相关推荐
- gRPC 基础概念详解
作者:jasonzxpan,腾讯 IEG 运营开发工程师 gRPC (gRPC Remote Procedure Calls) 是 Google 发起的一个开源远程过程调用系统,该系统基于 HTTP/ ...
- ROS wiki系列|ROS入门基础概念讲解
上一期我们对ROS wiki中ROS部分进行了着重讲解,回顾戳这 这一期我们主要介绍ROS-getting started部分的一些基本概念 相关wiki页面:http://wiki.ros.org/ ...
- .net中6个重要的基础概念:Stack, heap, Value types, reference types, boxing and Unboxing.
原文地址:http://www.codeproject.com/KB/dotnet/6importentStepsDotNet.aspx 因为文中的因为都比较简单. 加上配有截图,就不全部翻译了. 这 ...
- 图论中的基础概念总结
总结下图论中的各种基础概念 所以有部分定义直接搬运了度娘啦~ 子图 设 为两个图(同为无向图或同为有向图),若 且 ,则称G'是G的子图,G是G'的母图,记作 ,又若 且 ,则 ...
- React + webpack 开发单页面应用简明中文文档教程(一)一些基础概念
React + webpack 开发单页面应用简明中文文档教程(一)一些基础概念 React 入门系列教程导航 React + webpack 开发单页面应用简明中文文档教程(一)一些基础概念 Rea ...
- 逻辑思维是运用计算机科学的基础概念,简析计算思维中的思维方式及思维本质...
龙源期刊网 http://doc.docsou.com 简析计算思维中的思维方式及思维本质 作者:张菡 来源:<科学与财富>2020年第01期 摘要:计算思维是运用计算机科学的基础概念求解 ...
- 【贪玩巴斯】Unity3D初学圣经(三)—— unity中的基础概念——scene场景,component组件,assets文件夹和Material材质,Mesh Renderer与shader
[贪玩巴斯]Unity3D初学圣经 三-- unity中的基础概念--scene场景,component组件与assets文件夹和Material材质以及Mesh Renderer 和 shader ...
- 腾讯云MLVB技术如何在移动直播服务中突出重围之基础概念
今天智密科技就来为刚刚进入视频直播程序开发的工程师们来讲解一下视频直播中的基础概念 RTMP 全称是 Real-Time Messaging Protocol (实时消息传输协议).最初由Macrom ...
- AI:人工智能领域之AI基础概念术语之机器学习、深度学习、数据挖掘中常见关键词、参数等5000多个单词中英文对照(绝对干货)
AI:人工智能领域之AI基础概念术语之机器学习.深度学习.数据挖掘中常见关键词.参数等5000多个单词中英文对照(绝对干货) 导读 本博主基本收集了网上所有有关于ML.DL的中文解释词汇,机 ...
最新文章
- Hive表与hdfs文件关联
- MAC OS X 10.8 操作远程SSH服务器 + 无密码输入使用SSH服务器
- 在mac上安装gitlab
- 【转】Windows Server 2012 R2 双网卡绑定
- 闲得无聊?不如用Python设计一个经典小游戏
- 常用的Oracle命令整理
- linux jar运行监控 mo,linux系统监控利器--monit
- java messagedigest_Java自带的加密类MessageDigest类代码示例
- 2021非常全的接口测试面试题及参考答案
- 电脑测试软件 免安装,Keyboard Test Utility:电脑必备键盘测试软件,小体积、免安装...
- IOU破局之路 | Focal EIOU:打破IOU/GIOU/CIOU的局限
- android rfid开发实例,Android NFC读卡 高频卡 RFID
- RK988键盘切换蓝牙模式
- 解决 CMD 命令行【不是内部或外部命令,也不是可运行的程序】或者【发生系统错误,拒绝访问】
- sudo: no tty present and no askpass program specified 处理
- Wed APIS-Window对象、本地存储、数组的map()方法、数组的join()方法
- 【笔记】网易微专业-Web安全工程师-01.WEB基础知识
- 当前页面实现简单搜索功能
- 2016电大计算机应用基础考试试题,(2016年电大)电大计算机应用基础考试_网考内容试题..doc...
- 卷积神经网络CNN常用的几个模型
热门文章
- HTML基础(一):常用标签1
- Android问题-selection contains a component,button7,introduced in an ancestor and cannot be deleted....
- 超34款吸费手机被曝光下架 天语TCL大显等在其中
- struts2上传文件时把文件放到服务器真实路径下的webapps\upload下
- java加vue实例_Vue.Js及Java实现文件分片上传代码实例
- 服务器操作系统分两大类,服务器的操作系统分哪几类
- outlook可以显示多少行文本_Linux学习从处理文本开始
- java方法重载_在Python中该如何实现Java的重写与重载
- 小程序获取openid保存缓存吗_小程序获取openid踩坑
- linux全网备份的原理,Linux面试题分享:Rsync(全网备份)和NFS(文件系统)