Java NIO 系列文章 (一) Buffer,Channel,Selector入门

前言

下面部分内容参考 Java NIO 系列教程-并发编程网

NIO类库简介

NIO 库是在JDK 1.4中引入的,NIO 弥补了原来同步阻塞 I/O 的不足,它在标准Java代码中提供了高速的,面向块的I/O。NIO的核心部分主要有:
- 通道 Channel
- 缓冲区 Buffer
- 多路复用器 Selector

下面一一介绍着三大核心部分。

通道 Channel

Channel 是一个通道,它就像自来水管一样,网络数据通过 Channel 读取和写入。

通道与流的不同之处在于:
- 通道是双向的,既可以从通道中读取数据,也可以写数据到通道,而流的读写通常是单向的,它只是在一个方向上移动
- 通道可以异步地读写
- 通道中的数据总是要先读到一个缓冲区Buffer,或者总是要从一个 Buffer 中写入

channel_buffer

Channel的实现

Channel本质是一个接口,它在有很多重要的实现
chanel
- FileChannel

FileChannel从文件中读取数据,也可以将数据写到文件中,FileChannel无法设置非阻塞模式,它总是运行在阻塞模式下。
- DatagramChannel
DatagramChannel通过UDP读写网络中的数据
- SocketChannel
SocketChannel通过TCP读写网络中的数据
- ServerSocketChannel
可以监听新进来的TCP连接,像 Web 服务器那样,对每一个新进来的连接都会创建一个SocketChannel。

SocketChannelServerSocketChannel 就对应 传统网络编程中的 Socket类ServerSocket类

Channel的例子

下面以 FileChannel为例来写一个关于通道与缓冲区的例子,代码如下:

public class ChannelTest {
   
    public static void main(String[] args) throws IOException {
        RandomAccessFile accessFile = new RandomAccessFile("C:\\Users\\Administrator\\Desktop\\nio-data.txt", "rw");
        //打开FileChannel
        FileChannel fileChannel = accessFile.getChannel();
        ByteBuffer byteBuffer = ByteBuffer.allocate(48);
        //从通道里读取数据到缓冲区
        int bytesRead = fileChannel.read(byteBuffer);
        while (bytesRead != -1) {
            System.out.println("Read: "+bytesRead);
            //反转
            byteBuffer.flip();
            //从缓冲区中读取数据
            while (byteBuffer.hasRemaining()) {
                System.out.print((char)byteBuffer.get());
            }
            byteBuffer.clear();
            bytesRead = fileChannel.read(byteBuffer);
        }
        accessFile.close();
    }
}
  • 在使用 FileChannel 之前,必须先打开它,我们无法直接打开它,需要通过一个InputStream,OutputStream或者RandomAccessFile 来打开它
  • 从 FileChannel 中读取数据,先分配一个Buffer(关于Buffer的介绍参见下文),调用 FileChannel 的read()方法,该方法返回的 int 值表示了有多少字节被读到了 Buffer 中

缓冲区 Buffer

在NIO库中,数据是从通道读入到缓冲区,从缓冲区写入到通道中的。

缓冲区本质上是一块可以写入的数据,然后可以从读取数据的内存。这块内存被封装成了 NIO Buffer 对象,并提供了一组方法,用来方便的访问该块内存。

Buffer的类型

Java NIO有以下几种Buffer 类型
buffer
- ByteBuffer: 字节缓冲区
- MappedByteBuffer: 用于实现内存映射文件
- CharBuffer: 字符缓冲区
- ShortBuffer: 短整型缓冲区
- IntBuffer: 整型缓冲区
- LongBuffer: 长整形缓冲区
- FloatBuffer: 浮点型缓冲区
- DoubleBuffer: 双精度浮点型缓冲区

Buffer的内部属性

缓冲区Buffer 内部就是用数组实现的。Buffer 包含了下面4个属性:
- Capacity (容量)

缓冲区能够容纳的数据元素的最大数量。这个容量在缓冲区创建时被设定,并且永远不会被改变。你只能往里写 capacity 个 byte,long,char等类型。一旦 Buffer 满了,需要将其清空 (通过读数据或者清除数据) 才能往里写数据

  • Limit (上界)

    缓冲区的第一个不能被读或写的元素,或者说缓冲区现存元素的上界。在写模式下,Buffer的limit 表示最多能往 Buffer 里写多少数据。写模式下,limit 等于 Buffer 的capacity。当切换Buffer到读模式,limit表示你最多能读到多少数据。此时limit会被设置成写模式下的position值。

  • Position (位置)

    缓冲区内下一个将要被读或写的元素位置,在进行读写缓冲区时,位置为自动更新。当你写数

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值