美文网首页
Netty 源码分析 —— NIO 基础(二)之 Channel

Netty 源码分析 —— NIO 基础(二)之 Channel

作者: 小安的大情调 | 来源:发表于2020-02-10 22:51 被阅读0次

我准备战斗到最后,不是因为我勇敢,是我想见证一切。 --双雪涛《猎人》

[TOC]
Thinking

  1. 一个技术,为什么要用它,解决了那些问题?
  2. 如果不用会怎么样,有没有其它的解决方法?
  3. 对比其它的解决方案,为什么最终选择了这种,都有何利弊?
  4. 你觉得项目中还有那些地方可以用到,如果用了会带来那些问题?
  5. 这些问题你又如何去解决的呢?

本文基于Netty 4.1.45.Final-SNAPSHOT

1、简述

​ Channel是JDK 1.4之后引入的NIO中非常重要的一个概念,所有的I/O操作必须通过Channel进行读写,不能直接操作缓冲区Buffer。(这里需要提醒的一点就是,Channel是双向的,既可以从通道中读取数据,又可以写数据到通道。)

那么Java NIO 中的通道(Channel)于传统BIO中的文件流有那些异同呢?

  • Channel即可以读取数据,又可以向里写数据。但是流的读写通常是单向的。
  • 通道可以异步地读写。
  • 通道中地数据总是要先读到一个Buffer中,或者总是要从一个Buffer中写入。

上述操作如图所示:


Channel通道双向读写数据.png

2、Channel

java.nio.channels.Channel

2.1、源码

public interface Channel extends Closeable {

    /**
     * Tells whether or not this channel is open.
        判断此通道是否处于打开状态
     *
     * @return <tt>true</tt> if, and only if, this channel is open
     */
    public boolean isOpen();

    /**
     * Closes this channel.
        关闭此通道
     *
     * <p> After a channel is closed, any further attempt to invoke I/O
     * operations upon it will cause a {@link ClosedChannelException} to be
     * thrown.
     *关闭通道后,
        任何进一步尝试在其上调用I / O 的操作都会导致抛出{@link ClosedChannelException}

     * <p> If this channel is already closed then invoking this method has no
     * effect.
        如果此通道已关闭,则调用此方法无效
     *
     * <p> This method may be invoked at any time.  If some other thread has
     * already invoked it, however, then another invocation will block until
     * the first invocation is complete, after which it will return without
     * effect. </p>
        可以随时调用此方法。但是,如果某个其他线程已经调用了它,
        则另一个调用将被阻塞,直到第一个调用完成为止,之后它将返回而没有任何效果
        
        就是在该Method 调用后,还是可以被调用的,但是如果此方法正在被调用,该操作是会被阻塞的。
        之后调用不会返回任何东西。

     *
     * @throws  IOException  If an I/O error occurs
     */
    public void close() throws IOException;

}

​ Channel有非常多的实现,其中有四个非常重要的类

2.2、类图

Channel类图.png
  • FileChannel :从文件中读写数据。
  • DatagramChannel :通过UDP读写网络中的数据。
  • SocketChannel :通过TCP读写网络中的数据。
  • ServerSocketChannel : 可以监听新进来的TCP连接,像Web服务器那样。对每一个新进来的连接都会创建一个SocketChannel。

2.3、示例

/**
 * Channel 示例
 * <p>
 * 使用FileChannel 读取文件 基于Buffer
 *
 * @author by Mr. Li
 * @date 2020/2/10 22:08
 */
@Slf4j
public class ChannelExample {
    public static void main(String[] args) throws Exception {
        RandomAccessFile file = new RandomAccessFile("E:/idea_workspace/springcloud2.0/netty/netty-mytest/src/main/resources/data/nio-data.txt", "rw");
        FileChannel channel = file.getChannel();

        // 获取 缓冲区
        ByteBuffer buf = ByteBuffer.allocate(1024);

        int read = channel.read(buf);
        while (read != -1) {
            log.info("Read Ended ,Message:{}", read);

            // 数组反转,才能读取
            buf.flip();
            while (buf.hasRemaining()) {
                log.info("Message:{}", buf.get());
            }

            // 清空缓冲区
            buf.clear();
            read = channel.read(buf);
        }
        file.close();
    }

}

本文仅供笔者本人学习,一起进步!

——努力努力再努力xLg

加油!

相关文章

网友评论

      本文标题:Netty 源码分析 —— NIO 基础(二)之 Channel

      本文链接:https://www.haomeiwen.com/subject/dszzxhtx.html