Java之IO学习(四)NIO通道缓存区

本文详细解析了NIO(非阻塞IO)与传统IO的主要区别,包括数据处理方式、通道与缓冲区的概念,以及如何利用NIO进行高效文件复制。通过实例展示了NIO在文件操作中的优势,如数据块处理、双向通道和缓冲区状态管理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

NIO时JDK1.4以后引入的,弥补了原咯爱IO的不足;

1、流与块:

IO和NIO的区别:

(1)IO一次处理一个字节,输入/输出均为一个字节

(2)NIO方式一次处理一个数据块

 

2、通道与缓冲区:

(1)通道(Channel):

通道是对原来的IO的流的模拟,与IO最大的区别在于IO只能是单向的要么输入要么输出,而通道则可以同时读也可以同时写。

通道包括:

  • FileChannel:从文件中读写数据;
  • DatagramChannel:通过 UDP 读写网络中数据;
  • SocketChannel:通过 TCP 读写网络中数据;
  • ServerSocketChannel:可以监听新进来的 TCP 连接,对每一个新进来的连接都会创建一个 SocketChannel。

(2)缓冲区:

发送到通道的数据都被首先存放在缓冲区中:

缓冲区包括:

  • ByteBuffer
  • CharBuffer
  • ShortBuffer
  • IntBuffer
  • LongBuffer
  • FloatBuffer
  • DoubleBuffer

(3)缓冲区变量内部过程:

状态变量三个值指定缓冲区任意时刻状态:

  • position(跟踪已经写了多少数据)

  • limit(表明还有多少数据需要取出(在从缓冲区写入通道时),或者还有多少空间可以放入数据(在从通道读入缓冲区时))

  • capacity(表明可以储存在缓冲区中的最大数据容量)

position 总是小于或者等于 limit,limit 决不能大于 capacity。

 

例如,Buffer状态如下:

limit 决不能大于 capacity,此例中这两个值都被设置为 8。我们通过将它们指向数组的尾部之后(如果有第8个槽,则是第8个槽所在的位置)来说明这点

 

1>、开始读取数据,存入缓冲区时,position设置为0,即指向第一个位置

第一次读取3个数据,则position位置指向第四个位置(0 + 3 = 3), limit不变化:

 

第二次读取2个数据,则position指向第6个位置(3+2=5),limit不变化:

 

2>、flip操作时

  1. 它将 limit 设置为当前 position。

  2. 它将 position 设置为 0

 

3>、开始数据写入时,从缓冲区取出数据写入通道:

第一次写入,向通道写入4个字节数据,position指向第5个位置,limit指向第6个位置:

 

第二次写入,向通道写入1个字节,则position位置变为6,此时limit等于position:

 

 

4>、最后clear

  1. 它将 limit 设置为与 capacity 相同。

  2. 它设置 position 为 0。

 

 

3、文件NIO实例:

public static void fastCopy(String src, String dist) throws IOException {

    /* 获得源文件的输入字节流 */
    FileInputStream fin = new FileInputStream(src);

    /* 获取输入字节流的文件通道 */
    FileChannel fcin = fin.getChannel();

    /* 获取目标文件的输出字节流 */
    FileOutputStream fout = new FileOutputStream(dist);

    /* 获取输出字节流的文件通道 */
    FileChannel fcout = fout.getChannel();

    /* 为缓冲区分配 1024 个字节 */
    ByteBuffer buffer = ByteBuffer.allocateDirect(1024);

    while (true) {

        /* 从输入通道中读取数据到缓冲区中 */
        int r = fcin.read(buffer);

        /* read() 返回 -1 表示 EOF */
        if (r == -1) {
            break;
        }

        /* 切换读写 */
        buffer.flip();

        /* 把缓冲区的内容写入输出文件中 */
        fcout.write(buffer);

        /* 清空缓冲区 */
        buffer.clear();
    }
}

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值