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

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u014252478/article/details/83578648

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)缓冲区:

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

缓冲区包括:

扫描二维码关注公众号,回复: 3873442 查看本文章
  • 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();
    }
}

猜你喜欢

转载自blog.csdn.net/u014252478/article/details/83578648