一. 什么是通道
I/O通道(Channel):
一种专门负责执行IO任务的处理机/处理器,具有执行I/O指令的能力,并通过执行通道程序来完成I/O操作,它的作用是建立独立的IO操作,将CPU从繁多的低速IO操作中解脱。
详细解释:
1. 当CPU和I/O设备之间增加设备控制器后,已经可以大大减少IO对CPU的依赖,而IO通道的出现是为了建立独立的IO操作,从而进一步减轻CPU的负担。
2. 通道管理设备控制器,而这些控制器控制着IO设备(如磁盘驱动器、终端、LAN端口),同时通道具有执行I/O指令的能力,与CPU交互。
3. 当需要执行IO操作时,CPU只需向通道发一条IO指令,通道执行通道处理程序,通过和设备控制器交互,开始IO操作;当IO操作完成后,通道向CPU发送信号;CPU在发送IO指令至接收到IO完成的信号期间可以运行和该IO操作无关的任务,使得CPU可以专门负责处理高速任务,低速的IO任务交给通道完成,整体任务处理效率得到提高。
4. 对于Java的nio,通道的意义在于对异步IO的支持,是nio的关键对象。
二. 什么是ByteBuffer
ByteBuffer,也称为字节缓冲区,也是Java nio的关键对象。
1. 通道负责处理IO操作,相对于应用程序,是IO数据的源头或目的地,而ByteBuffer是应用程序和通道之间进行IO数据传输的中转地/缓冲区,且是nio中唯一直接和通道交互的缓冲区。
2. ByteBuffer本质是内存的一块区域,可存放原始字节。
相关内容(Linux的基础IO模型):
a. Linux的内核将所有外部设备都可以看做文件来操作。应用程序与外部设备的操作都可以看成对文件进行操作。应用程序对文件的读写,都通过调用内核提供的系统调用;内核给我们返回一个file descriptor(简称:fd,文件描述符);通过 ls -l /proc/${pid}/fd/ 可以看到进程${pid}占用的所有描述符,或者lsof -p ${pid}; 而对一个socket的读写也会有相应的描述符,称为socketfd(socket描述符);描述符就是一个数字,指向内核中一个结构体(文件路径,数据区,等一些属性) ; 那么应用程序对文件的读写就通过对描述符的读写完成。
b. 系统调用是如何完成一个I/O操作的呢? linux将内存分为内核区,用户区;应用程序通过调用系统调用和内核交互,使用Linux所有的硬件资源;如通过系统调用read发起一个读操作,此时内核创建一个文件描述符,并通过驱动程序向硬件发送读指令,并将读的的数据放在这个描述符对应结构体的缓存区。但这个结构体是在内核内存区的。需要将这个数据读到用户区的内存,这样完成了一次读操作,如果应用程序是通过java nio方式读取,那么该前述用户区的内存就是ByteBuffer;write操作类似。
c. 但是大家都知道I/O设备相比cpu的速度是极慢的。linux提供的read系统调用,也是一个阻塞函数。这样我们的应用进程在发起read系统调用时,就必须阻塞,就进程被挂起而等待文件描述符的读就绪。
什么是文件描述符读就绪,什么是写就绪?
读就绪:就是这个文件描述符的接收缓冲区中的数据字节数大于等于套接字接收缓冲区(可认为是byteBuffer)低水位标记的当前大小;
写就绪:该描述符发送缓冲区的可用空间字节数大于等于描述符发送缓冲区(可认为是byteBuffer)低水位标记的当前大小。如果是socket fd,说明上一个数据已经发送完成)。
接收低水位标记和发送低水位标记:由应用程序指定,比如应用程序指定接收低水位为64个字节。那么接收缓冲区有64个字节,才算fd读就绪;
d.小结: 对于Linux的基础IO模型,byteBuffer是用户区的存放数据的缓冲区,与内核区的结构体缓存区对应,是IO数据在内核(通道属于内核)和应用程序之间传送的中转站;而上述的关于IO操作的内核系统调用相当于通道处理程序。
ps:Linux的基础IO模型的引用博客: 深入浅出异步I/O模型 http://alicsd.iteye.com/blog/868702
相关推荐
NIO的核心特性包括基于缓冲区的I/O操作和非阻塞I/O,这使得应用程序能够处理更多的连接,同时减少资源的消耗。 NIO API主要分布在以下几个包中: 1. `java.nio`:这个包定义了Buffer及其子类,例如ByteBuffer,...
- **定义**:通道(Channel)是 Java NIO 中的重要组成部分,它可以理解为一种双向的数据流,支持从通道读取数据到缓冲区,或从缓冲区写入数据到通道。 - **特点**: - 双向性:不同于传统的流只能进行单一方向的...
直接字节缓冲区可以通过 `allocateDirect()` 方法创建。 ### 四、Java NIO 的三个核心组件 1. **Buffer(缓冲区)**:用于存储数据,是 NIO 中所有 I/O 操作的基础。 2. **Channel(通道)**:用于连接缓冲区和...
- **通道(Channel)**:用于源与缓冲区或另一个通道之间传输数据。通道的主要实现包括: - `FileChannel` - `SocketChannel` - `DatagramChannel` - `Pipe.SinkChannel` - `Pipe.SourceChannel` - **选择器...
- **Buffers**:Buffers提供了数据缓冲区的概念,允许数据在Channel和应用程序之间传输。Buffers不仅可以存储原始数据,还提供了一系列方法来控制数据的读写操作,如`put()`、`get()`等。 - **Selectors**:...
1. **`java.nio`**: 定义了各种类型的缓冲区(Buffer),包括`ByteBuffer`、`CharBuffer`等。 2. **`java.nio.channels`**: 提供了一系列通道(Channel)接口及其具体实现,支持文件和网络的I/O操作。 3. **`java.nio....
Channel(通道)是 Java NIO 中的一种 fundamental component,它提供了对 I/O 服务的直接连接,允许开发者高效地传输数据 zwischen 字节缓冲区和位于通道另一侧的实体(通常是一个文件或套接字)。在 Java NIO 中,...
NIO还支持直接缓冲区(Direct Buffer),这种缓冲区直接在本地内存中分配空间,避免了Java堆和本地内存之间的数据复制,从而提高了性能。 ##### 3. 异步I/O 除了非阻塞I/O外,NIO还支持异步I/O操作。在某些情况下...
1. **基于通道(Channel)和缓冲区(Buffer)的操作**:与标准 IO 基于字节流和字符流的操作不同,NIO 使用 Channel 和 Buffer 进行数据传输。 2. **非阻塞 IO**:NIO 支持非阻塞模式,这意味着线程可以在等待 IO 操作的...
通过引入缓冲区和通道等概念,NIO实现了高效、非阻塞的数据传输,尤其适用于需要处理大量并发连接的场景。对于现代软件开发来说,掌握NIO是非常重要的,它不仅可以帮助我们构建更加健壮和高效的系统,还能更好地应对...
在 NIO 中,所有的数据都是用缓冲区处理的,读取数据时,它是从通道(Channel)直接读到缓冲区中,在写入数据时,也是从缓冲区写入到通道。缓冲区实质上是一个数组,通常是一个字节数组(ByteBuffer),也可以是其它...
#### 二、Buffer & Channel(缓冲区与通道) **Buffer** 和 **Channel** 是NIO中的两个核心概念。 1. **Buffer是什么?** - **定义**:`Buffer`是一个包含数据的对象,用于读写操作。在NIO中,所有数据的读写都...
- **直接缓冲区**:NIO 提供了直接缓冲区,数据可以直接在内存和缓冲区之间传递,减少了数据复制的开销。 #### 四、NIO 的应用场景 NIO 的优势使其在多种场景下有着广泛的应用: - **网络编程**:特别是在服务器...
传统的Java IO基于字节流和字符流,而NIO则基于通道(Channel)和缓冲区(Buffer)进行操作,这种方式更有效率,尤其在处理大量并发I/O操作时。 ** Channels and Buffers** 在Java NIO中,数据总是在通道(Channel...
- **Capacity**:缓冲区的总容量,即可以存储的最大数据量。 Buffer的操作流程通常包括: 1. **clear()**:重置buffer,使其准备好接收新的数据。 2. **flip()**:将buffer从写模式切换到读模式。 3. **rewind()**...
2. ByteBuf:Netty自定义的高效字节缓冲区,替代了Java的ByteBuffer,提供了更友好的API和内存管理。 3. 通道处理器:ChannelHandler是处理网络事件的核心接口,可以定制实现各种业务逻辑。 4. 通道管道:...
**NIO简介**:NIO是一种基于通道(Channel)与缓冲区(Buffer)的I/O操作方式,相比于传统的BIO(Blocking I/O),它最大的特点是支持非阻塞模式,即应用程序在进行I/O操作时不会被阻塞,这极大地提高了系统的并发处理...