摘自并发编程网:http://ifeve.com/overview/
仅作自己学习……
1. FileChannel
Java NIO中的FileChannel是一个连接到文件的通道。可以通过文件通道读写文件。FileChannel无法设置为非阻塞模式,它总是运行在阻塞模式下。
在使用FileChannel之前,必须先打开它。但是,我们无法直接打开一个FileChannel,需要通过使用一个InputStream、OutputStream或RandomAccessFile来获取一个FileChannel实例。
调用多个read()方法之一从FileChannel中读取数据。首先,分配一个Buffer,从FileChannel中读取的数据将被读到Buffer中,该方法将从数据从FileChannel读取到Buffer中,read方法返回的int值代表有多少字节被读到了Buffer中,如果返回-1,表示到了文件末尾。
使用FileChannel.write()方法是在while循环中调用的。因为无法保证write方法一次能向FileChannel中写入多少个字节,需要重复调用,直到Buffer中已经没有尚未写入通道的字节。
在用完FileChannel后必须将其关闭。
有时可能需要在FileChannel的某个特定位置进行数据的读写操作,就可以通过调用position()方法获取FileChannel的当前位置,也可以通过调用position(long pos)来设置FileChannel的当前位置。如果将位置设置在文件结束符之后,然后试图从文件通道中读取数据,读方法将返回-1 —— 文件结束标志。如果将位置设置在文件结束符之后,然后向通道中写数据,文件将撑大到当前位置并写入数据。这可能导致“文件空洞”,磁盘上物理文件中写入的数据间有空隙。
FileChannel的size方法将返回该实例所关联的文件大小。使用FileChannel的truncate方法可以截取一个文件,截取文件时,文件指定长度后面的部分将会被删除。FileChannel的force方法将通道里尚未写入磁盘的数据强制写到磁盘中。出于性能考虑,操作系统会将数据缓存在内存中,所以无法保证写入到Channel中的数据一定会即时写入到磁盘中,要保证这一点,必须要使用force方法。force中的Boolean参数指定是否同时将文件元数据(权限信息等)写入到磁盘中。
2. SocketChannel
Java NIO中的SocketChannel是一个连接到TCP网络套接字的通道。可以通过以下2种方式创建SocketChannel:
- 打开一个SocketChannel并连接到互联网上的某台服务器。
SocketChannel socketChannel = SocketChannel.open(); socketChannel.connect(new InetSocketAddress(IPAddress, PORT));
- 一个新连接到达ServerSocketChannel时,会创建一个SocketChannel。
在使用完SocketChannel后调用close方法关闭。
如果要从SocketChannel中读取,调用read方法。首先,要分配一个Buffer,从SocketChannel中读到的数据将会放到这个Buffer中;read方法返回的int值表示读了多少字节进入到Buffer中,如果返回的是-1,表示已经读到流的末尾(连接关闭)。
写数据到SocketChannel中调用write方法,该方法以一个Buffer作为参数。其调用也是在一个while循环中,write方法无法保证写多少个字节到SocketChannel中,所以我们要重复调用write直到Buffer没有要写的字节为止。
可以设置SocketChannel在非阻塞模式下运行,此时调用connect,该方法可能会在连接建立之前就已经提前返回了。同理,非阻塞模式下的write和read方法可能会在尚未写入或读取任何内容后就返回了。
非阻塞模式与选择器搭配会工作得更好,通过将一个或者多个SocketChannel注册到Selector,可以询问哪个通道已经准备好读取/写入等。
3. ServerSocketChannel
Java NIO中的 ServerSocketChannel 是一个可以监听新进来的TCP连接的通道, 就像标准IO中的ServerSocket一样,ServerSocketChannel类在 java.nio.channels包中。
调用 ServerSocketChannel.open() 静态方法来打开ServerSocketChannel,调用close来进行关闭和清理资源。
通过 ServerSocketChannel.accept() 方法监听新进来的连接,当accept()方法返回的时候,它返回一个包含新进来的连接的SocketChannel,accept()方法会一直阻塞到有新连接到达。
ServerSocketChannel可以设置成非阻塞模式。在非阻塞模式下,accept() 方法会立刻返回,如果还没有新进来的连接,返回的将是null。因此,需要检查返回的SocketChannel是否是null。
4. DatagramChannel
Java NIO中的DatagramChannel是一个能收发UDP包的通道,UDP是无连接的网络协议,不能像其它通道那样读取和写入,它发送和接收的是数据包。
调用DatagramChannel.open()
方法并绑定对应的端口来接收数据包,
使用
receive
方法从
DatagramChannel
中读取数据,
receive
方法会将接收到的数据包复制到指定
Buffer
,如果
Buffer
容纳不下收到的所有数据,多出来的数据将会被抛弃。
通过调用
send
方法来从
DatagramChannel
发送数据。因为服务器可能并没有监控发送数据的端口,
UDP
也不会先进行连接的建立,因此可能发送数据包丢失的现象。
可以将
DatagramChannel
连接到网络中的特定地址,由于
UDP
是无连接的,连接到特定地址只会锁住
DatagramChannel
,让其在特定地址收发数据。
5. Pipe
Java NIO Pipe是2个线程之间的单向数据连接。Pipe有一个source通道和一个sink通道。数据会被写入到sink通道,从source通道中读取。
通过Pipe.open()方法来打开管道,返回一个Pipe对象。如果想要向管道写数据,需要访问sink通道,执行pipe.sink()方法,向返回的SinkChannel中写入数据。
如果想要从管道中读取数据,需要访问source通道,执行pipe.source()方法,从返回的SourceChannel中读取数据。
当前,Channel的读取和写入都要和Buffer打交道。
6. Java NIO与IO
6.1 主要区别
IO |
NIO |
面向流 |
面向缓冲 |
阻塞IO |
非阻塞IO |
无 |
选择器 |
6.2 面向流和面向缓冲
Java NIO和IO之间第一个最大的区别是,IO是面向流的,NIO是面向缓冲区的。 Java IO面向流意味着每次从流中读一个或多个字节,直至读取所有字节,它们没有被缓存在任何地方。此外,它不能前后移动流中的数据。如果需要前后移动从流中读取的数据,需要先将它缓存到一个缓冲区。Java NIO的缓冲导向方法略有不同,数据读取到一个它稍后处理的缓冲区,需要时可在缓冲区中前后移动。这就增加了处理过程中的灵活性。但是,还需要检查是否该缓冲区中包含所有需要处理的数据。而且,需确保当更多的数据读入缓冲区时,不要覆盖缓冲区里尚未处理的数据。
6.3 阻塞与非阻塞IO
Java IO的各种流是阻塞的。这意味着,当一个线程调用read()或write()时,该线程被阻塞,直到有一些数据被读取,或数据完全写入。该线程在此期间不能再干任何事情了。Java NIO的非阻塞模式,使一个线程从某通道发送请求读取数据,但是它仅能得到目前可用的数据,如果目前没有数据可用时,就什么都不会获取。而不是保持线程阻塞,所以直至数据变的可以读取之前,该线程可以继续做其他的事情。非阻塞写也是如此。一个线程请求写入一些数据到某通道,但不需要等待它完全写入,这个线程同时可以去做别的事情。线程通常将非阻塞IO的空闲时间用于在其它通道上执行IO操作,所以一个单独的线程现在可以管理多个输入和输出通道(channel)。
6.4 选择器
Java NIO的选择器允许一个单独的线程来监视多个输入通道,你可以注册多个通道使用一个选择器,然后使用一个单独的线程来“选择”通道:这些通道里已经有可以处理的输入,或者选择已准备写入的通道。这种选择机制,使得一个单独的线程很容易来管理多个通道。
6.5 NIO和IO影响应用程序的设计
使用NIO的API调用时看起来与使用IO时有所不同,IO是仅从一个InputStream逐字节读取,而NIO是数据必须先读入缓冲区再处理。
IO的数据读取模型:
NIO的数据读取模型:
NIO可让您只使用一个(或几个)单线程管理多个通道(网络连接或文件),但付出的代价是解析数据可能会比从一个阻塞流中读取数据更复杂。
如果需要管理同时打开的成千上万个连接,这些连接每次只是发送少量的数据,例如聊天服务器,实现NIO的服务器可能是一个优势。同样,如果你需要维持许多打开的连接到其他计算机上,如P2P网络中,使用一个单独的线程来管理你所有连接,可能是一个优势。如果你有少量的连接使用非常高的带宽,一次发送大量的数据,也许典型的IO服务器实现可能非常契合。
相关推荐
ByteBuffer的用法是Java NIO学习中的核心内容。 首先,我们了解下ByteBuffer的基本概念。ByteBuffer是一个字节缓冲区,可以存储字节序列。在NIO中,所有的数据读写都通过缓冲区进行,ByteBuffer与其他类型的Buffer...
### Java NIO 学习笔记 #### 一、概述 Java NIO (Non-Blocking IO,也称为 Java New IO),是 Java 对传统 IO 模型的一次重大改进,旨在提高程序处理大量并发连接的能力。NIO 的核心组件包括 Channels、Buffers 和 ...
Java NIO(New Input/Output)是Java标准库在JDK 1.4引入的一组新的I/O API,它提供了一种不同于传统IO的高效、非阻塞的I/O操作方式。NIO的核心概念包括Channel、Buffer和Selector,它们共同构建了一个与操作系统...
java学习笔记1(java io/nio)设计模式
NIO的主要特点是其能够使Java程序以更有效的方式处理I/O流,尤其在高并发场景下,NIO能显著提高程序的性能。 NIO的核心概念包括: 1. **通道(Channel)**:与传统的流相比,通道是双向的,可以读也可以写。Java NIO...
Java NIO(New Input/Output)是Java标准库在JDK 1.4版本中引入的一个新特性,它提供了一种不同于传统IO流的高效I/O处理方式。NIO的核心概念包括通道(Channel)和缓冲区(Buffer),这两个组件使得数据以块的形式...
自己总结的java中NIO的笔记,绘制了详细的思维导图,每个思维导图中均有详细的博文解释,方便大家学习和理解,免费分享给大家。适合java的爱好者和学习者
Java NIO库提供了多种实现,如`java.nio.channels`包下的各种Channel和Selector类,以及`java.nio`包下的Buffer类。 在学习NIO时,首先需要理解Channel、Buffer、Selector的基本概念和使用方法,然后通过实例来熟悉...
《JAVA学习笔记》是林信良先生的一部深入浅出的Java编程教程,旨在帮助初学者和有一定经验的开发者巩固和提升Java编程技能。这本书涵盖了Java语言的基础到高级概念,是一份宝贵的自学资料。 首先,从基础部分开始,...
这个PDF学习笔记是开发者深入理解JDK 7特性和功能的重要参考资料。以下是对Java JDK 7的一些核心知识点的详细阐述: 1. **泛型改进**:在JDK 7中,泛型的使用更加灵活,引入了类型推断(Type Inference)特性,通过...
5. **IO流与NIO**:Java的IO流和NIO(非阻塞I/O)用于读写数据,笔记会介绍文件操作、网络通信、数据传输等场景下的使用方法。 6. **多线程**:Java提供了内置的多线程支持,笔记会讲解线程的创建、同步、通信等,...
【Java基础】 Java是一种广泛使用的面向对象的编程语言,由Sun Microsystems(现已被Oracle公司收购)于1995年发布。Java以其“一次编写,到处运行”的特性...通过深入学习和实践,你可以不断提升自己的Java编程能力。
“尚硅谷JAVA基础笔记”涵盖了Java语言的基础知识,包括语言概述、基本语法、面向对象概念、封装、继承和多态,以及一些关键概念如形参与实参、属性与局部变量、构造器、this关键字、包和MVC设计模式的使用。...
《良葛格JAVA 学习笔记》是由知名IT专家林信良,网名“良葛格”,在台湾大学电机工程学系的深厚学术背景基础上,结合其作为SUN教育训练中心讲师的丰富教学经验编写的。他的著作还包括《Spring 技术手册》,并且他...
Java JDK 6学习笔记是为Java初学者量身定制的一份宝贵资料,它涵盖了Java编程的基础概念、语法以及核心特性。这份PPT简体版旨在帮助读者快速掌握Java开发的基本技能,逐步成为一名合格的Java程序员。 Java JDK...
这份《java学习》笔记包含了多个核心主题,旨在帮助初学者和有经验的开发者深入理解和掌握Java技术。 1. **正则表达式(正则.md)**: 正则表达式在Java中用于文本匹配和搜索,是处理字符串的强大工具。Java提供了...
《NIO学习笔记》 在Java编程领域,NIO(Non-blocking Input/Output,非阻塞I/O)是一种重要的I/O模型,与传统的BIO(Blocking I/O)相对应。NIO提供了一种新的方式来处理I/O操作,特别是在处理大量并发连接时,它的...
这个压缩包“Java JDK 6学习笔记.zip”显然是一个包含有关Java JDK 6深入学习资源的集合,可能是PDF文档、笔记或者其他形式的教学材料。 在Java JDK 6中,有几个关键的特性值得我们关注: 1. **改进的性能**:JDK ...
《良葛格Java学习笔记(完整版)》是一份全面且深入的Java编程教程,适合不同层次的Java学习者,无论你是初学者还是有经验的开发者,都能从中受益。这份笔记详细介绍了Java语言的核心概念、语法特性以及实际开发中的...