Java NIO:NIO概述
http://www.cnblogs.com/dolphin0520/p/3919162.html
在上一篇博文中讲述了几种IO模型,现在我们开始进入Java NIO编程主题。NIO是Java 4里面提供的新的API,目的是用来解决传统IO的问题。本文下面分别从Java NIO的几个基础概念介绍起。
以下是本文的目录大纲:
一.NIO中的几个基础概念
二.Channel
三.Buffer
四.Selector
若有不正之处,请多多谅解并欢迎批评指正。
请尊重作者劳动成果,转载请标明原文链接:
http://www.cnblogs.com/dolphin0520/p/3919162.html
一.NIO中的几个基础概念
在NIO中有几个比较关键的概念:Channel(通道),Buffer(缓冲区),Selector(选择器)。
首先从Channel说起吧,通道,顾名思义,就是通向什么的道路,为某个提供了渠道。在传统IO中,我们要读取一个文件中的内容,通常是像下面这样读取的:
1
2
3
4
5
6
7
8
9
|
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来向文件中写入数据的一个例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
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个类构成了服务端处理业务的关键逻辑。
关于Selector类的具体使用将在后续文章中阐述。
参考资料:
http://blog.csdn.net/wuxianglong/article/details/6604817
http://www.360doc.com/content/12/0515/11/1542811_211144310.shtml
http://www.iteye.com/topic/834447
http://weixiaolu.iteye.com/blog/1479656
相关推荐
在本文中,我们将深入探讨Xilinx公司的xdma驱动下的底层读写DLL封装技术,这是针对PCI Express(PCIE)开发中的一个关键环节。Xilinx的xdma IP核是用于实现高性能PCIE接口的一种解决方案,而将底层读写操作封装成DLL...
**iocp网络底层封装** 在Windows操作系统中,I/O完成端口(I/O Completion Port,简称IOCP)是一种高效的多线程并发I/O处理机制。它允许开发者将多个异步I/O操作关联到一个单一的完成端口,从而实现线程池的高效...
本文将深入探讨iOS网络底层的实现,主要涉及BSD Socket、CFNetwork和NSStream这三个关键组件。理解并掌握这些技术,对于优化网络性能、处理复杂网络场景以及编写高效、可靠的网络代码至关重要。 首先,我们来看**...
因此,RFID标准化组织EPCglobal在2007年推出了底层读写器协议LLRP(Low Level Reader Protocol),它为读写器和其控制器提供了标准的网络接口,极大地提高了RFID应用系统的构建效率。借助于开源的RFID中间件平台...
在C或C++中实现XML文件的读写解析底层涉及到多个关键概念和技术,下面将详细阐述这些知识点。 1. **基础概念**: - **XML语法**:XML文档遵循一套严格的语法规则,包括元素、属性、文本内容、命名空间等。正确解析...
在高性能服务器的底层网络通信模块设计方面,文档中提出的设计方案在I/O完成端口的基础之上进行了封装,目标是创建一个具有高性能和可扩展性的通用网络通信模块。为了达到这样的目标,设计中采用了一些关键的系统...
描述中提到的“可过tp读写大部分tp游戏”,这里的“tp”可能指的是反作弊系统(T Punk或类似的简称),这些系统通常用于网络游戏,以防止玩家通过修改内存数据进行作弊。驱动能够绕过这样的保护机制,意味着它具有较...
总结,易语言驱动技术是易语言在系统编程领域的重要组成部分,通过驱动读写源码的学习,我们可以更好地理解底层操作系统的工作机制,提升编程能力。同时,正确、合法地运用这些技术,可以推动游戏开发和系统优化等...
"底层网络库"主要关注的是操作系统提供的网络编程接口,这些接口允许开发者处理网络数据的传输和接收。本篇文章将详细探讨标题和描述中提到的两个关键概念:`select`和`epoll`,以及它们在网络编程中的应用。 首先...
在编程领域,网络字节流读写文件是网络通信和数据传输中的常见操作。本文将深入探讨C++、Java、PHP和C#这四种语言在网络字节流读写文件方面的实现,以及它们各自的特点和差异。 首先,让我们从C++开始。C++提供了一...
这种方法需要对底层系统有较深的理解。 5. 磁盘剩余空间: 获取磁盘剩余空间,可以使用QDir类的`space()`方法,传入`QDir::Free`作为参数,它会返回指定目录所在分区的可用空间。 在实际应用中,可以创建一个监控...
在Go语言中,`raw`包提供了一种方式来直接操作网络接口的设备驱动程序级别数据,这使得开发者可以实现更底层的网络通信,比如抓包、协议分析或者自定义网络协议栈。本文将深入探讨如何使用Go的`raw`包进行网络编程,...
在Linux系统中,SMI(System Management Interface)和MDIO(Management Data Input/Output)总线是用来与PHY(Physical Layer)芯片进行通信的接口...同时,这样的实践也能帮助我们更好地理解底层网络硬件的工作原理。
在Linux操作系统中,网卡(网络接口卡)的读写编程是通过与内核通信来完成的,...以上就是关于Linux网卡读写编程的基本知识,通过理解和掌握这些,开发者可以编写出能够直接与网卡交互的程序,实现更底层的网络控制。
2. WorkerGroup:处理实际的网络读写事件。WorkerGroup由多个工作线程组成,这些线程负责处理来自BossGroup的连接、读取数据、写入数据以及执行用户定义的业务逻辑。这样可以确保每个连接的读写操作不会阻塞其他连接...
而.NET作为微软的跨平台开发框架,支持多种编程语言,包括C#和VB.NET,适合构建现代、网络化的应用程序。这些示例代码不仅为初学者提供了学习的范例,也为有经验的开发者提供了实操的参考。 开发者能够通过这些示例...
API是操作系统或库提供的函数集,允许程序员通过调用这些函数来执行特定的任务,如文件操作、网络通信或硬件控制。在易语言中,调用API需要正确地声明和使用API函数,通常通过“.dll”动态链接库来实现。这个项目中...
本技术文档“一种用于在线读写安卓设备底层数据的程序及方法”聚焦于如何高效且安全地实现这一目标。 首先,我们要理解“底层数据”在安卓系统中的含义。底层数据通常指的是系统的内核级数据,包括硬件驱动、系统...
在Java编程中,数据读写和IO操作是至关重要的部分,尤其在处理文件、网络通信以及数据库交互时。本资源包含的"数据读写操作API"提供了一个方便的工具集,帮助开发者避免直接操作底层的IO流,简化了数据处理过程。这...
这些类在读写时会先存储一定量的数据,减少对底层物理设备的频繁访问。 4. 转换流(InputStreamReader/OutputStreamWriter):字节流与字符流之间的桥梁,用于在字节流和字符流之间转换。例如,如果要从一个字节...