NIO基础(二)之Channel

概述

在 Java NIO 中,基本上所有的 IO 操作都是从 Channel 开始。程序可以通过 Channel 读取文件中的内容并写到 Buffer 中(对于 Channel 来说是调用 read(),对于 Buffer 来说是写过程),也可以通过 Channel 读取 Buffer 中的内容并写到文件中(对于 Channel 来说是调用write(),对于 Buffer 来说是读过程)如下图所示:
Channel与Buffer

形象的描述

在上一期 Buffer 详解的示例中,我们演示过了如何将一个文件的内容拷贝到另一个文件中。我们可以将源文件理解为一座矿山,目标文件理解为目的地,我们的程序就是一个中转站。我们要做的就是:

  1. 打通两端的隧道,一个用于输入(从源矿山到中转站),一个用于输出(从中转站到目的地)。
FileChannel in = new FileInputStream(args[0]).getChannel(),
                out = new FileOutputStream(args[1]).getChannel();
  1. 打造一列用来运矿的矿车,制定它的大小,他有多少节车厢。
ByteBuffer buffer = ByteBuffer.allocate(BSIZE);
  1. 用于输入的隧道将矿装进矿车,并运到中转站。最后要在车箱上做好标记,确定卸货时,从哪节车箱开始,从哪节结束。
in.read(buffer);
buffer.flip();
  1. 用于输出的隧道将矿运到目的地,并卸货。最后要在车箱上做好标记,确定可以下次装货时,可以从头装到尾。
 out.write(buffer);
 buffer.clear();
  1. 如果还有需要运输的矿,重复3和4。
 while(in.read(buffer)!=-1) {
            //in调用read()后,数据输入到buffer,buffer内部指针位置改变,
            // buffer就要调用flip(),对内部指针重新安排,以便out.write()提取。
            buffer.flip();
            out.write(buffer);
            //out调用write()后,数据仍在buffer中,buffer内部指针位置改变,
            //clear()对内部指针重新安排,以便buffer在另一个in.read()操作期间能够做好接收数据的准备。
            buffer.clear();
        }
  1. 运输完毕,关闭隧道。
in.close();
out.close();

NIO Channel 对比 IO Stream

  1. 对于同一个 Channel ,我们可以从它读取数据,也可以向它写入数据。而对于同一个 Stream ,通常要么只能读,要么只能写,二选一。
  2. Channel 可以非阻塞的读写 IO 操作,而 Stream 只能阻塞的读写 IO 操作。
  3. Channel 必须配合 Buffer 使用,总是先读取到一个 Buffer 中,又或者是向一个 Buffer 写入。也就是说,我们无法绕过 Buffer ,直接向 Channel 写入数据。

Channel 的实现

Channel为一个抽象接口:

public interface Channel extends Closeable {

    public boolean isOpen();

    public void close() throws IOException;

}

它有4个重要的实现:

  • SocketChannel :一个客户端用来发起 TCP 的 Channel 。
  • ServerSocketChannel :一个服务端用来监听新进来的连接的 TCP 的 Channel 。对于每一个新进来的连接,都会创建一个对应的 SocketChannel 。
  • DatagramChannel :通过 UDP 读写数据。
  • FileChannel :从文件中,读写数据。
©️2020 CSDN 皮肤主题: 岁月 设计师: pinMode 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值