前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >NIO系列(二)——Channel通道复制和Selector选择器

NIO系列(二)——Channel通道复制和Selector选择器

作者头像
逝兮诚
发布2019-10-30 13:38:27
3940
发布2019-10-30 13:38:27
举报
文章被收录于专栏:代码人生代码人生

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:https://blog.csdn.net/luo4105/article/details/73650007

Channel通道

NIO通过通道来读写数据

Channel有以下实现类

FileChannel:文件读写通道。

DatagramChannel:通过UDP读写网络中的数据。

SocketChannel:通过TCP读写网络中的数据。

ServerSocketChannel:监听新进来的TCP连接,对每个新进来的连接都会创建一个SocketChannel。

Channel读取数据的方式与Buffer相似,也存在position定位。如定位末尾

fileChannel.position(fileChannel.size())

通道的数据复制

通道之间,可以通过transferTo、transferFrom来进行数据的复制。

transferTo(position, count, toChannel);

数据传输到toChannel 通道,position是复制开始的坐标、count是复制长度、toChannel是复制的目标通道。

transferFrom(position, count, fromChannel);

从fromChannel 通道复制数据,position是复制开始的坐标、count是复制长度、fromChannel是通道对象。

例子

这个例子是将fromFile.txt文件复制到toFile.txt中。在这个复制中,toFile.txt文件中在count内的内容将被改写,而超过count的内容将保持不变。

@Test
public voidtransferTo() throwsIOException {
    RandomAccessFile fromfile= new RandomAccessFile("src/main/resources/fromFile.txt", "r");
    FileChannel fromChannel= fromfile.getChannel();
   
    RandomAccessFile tofile= new RandomAccessFile("src/main/resources/toFile.txt", "rw");
    FileChannel toChannel= tofile.getChannel();
   
    fromChannel.transferTo(0, fromChannel.size(), toChannel);
}

Selector选择器

Selector选择器可以监听多个Channel通道感兴趣的事情(read、write、accept(服务端接收)、connect,实现一个线程管理多个Channel,节省线程切换上下文的资源消耗。Selector只能管理非阻塞的通道,FileChannel是阻塞的,无法管理。

关键对象

Selector:选择器对象,通道注册、通道监听对象和Selector相关。

SelectorKey:通道监听关键字,通过它来监听通道状态。

监听注册

监听注册在Selector

socketChannel.register(selector, SelectionKey.OP_READ);

监听的事件有

OP_ACCEPT: 接收就绪,serviceSocketChannel使用的

OP_READ: 读取就绪,socketChannel使用

OP_WRITE: 写入就绪,socketChannel使用

OP_CONNECT: 连接就绪,socketChannel使用

可以用过OP_READ| OP_WRITE方式注册多个事件

socketChannel.register(selector, SelectionKey.OP_READ|SelectionKey.OP_WRITE|SelectionKey.OP_CONNECT);

例子

public classSelectorTest {
    Selectorselector= null;
    SocketChannelsocketChannel = null;
   
    @Before
    public void before(){
       try {
           selector = Selector.open();
           socketChannel = SocketChannel.open();
           socketChannel.connect(new InetSocketAddress("127.0.0.1",9999));
           socketChannel.configureBlocking(false);
       }catch(IOException e) {
           e.printStackTrace();
       }
    }
 
    @Test
    public void selectorTest() throws IOException {
       socketChannel.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE | SelectionKey.OP_CONNECT);
       while (true) {
           int n = selector.select();
           if (n == 0)
              continue;
           Iterator keyIterator= selector.selectedKeys().iterator();
           while (keyIterator.hasNext()) {
              SelectionKey key1= (SelectionKey) keyIterator.next();
              if (key1.isAcceptable()) {
                  System.out.println("服务端接收就绪");
              }else if(key1.isConnectable()){
                  System.out.println("客户端连接接续");
              }else if(key1.isReadable()){
                  System.out.println(key1.hashCode() + "读取就绪");
                  SocketChannel socketChannel1= (SocketChannel) key1.channel();
                  ByteBuffer bBuffer= ByteBuffer.allocate(48);
                  for (int readSize = socketChannel1.read(bBuffer); readSize != -1; readSize = socketChannel1
                         .read(bBuffer)) {
                     if (readSize == 0)
                         continue;
                     bBuffer.flip();
                     System.out.println(Charset.forName("UTF-8").decode(bBuffer));
                     bBuffer.clear();
                  }
                  socketChannel1.close();
              }elseif(key1.isWritable()){
                  System.out.println(key1.hashCode() + "写入就绪");
              }
              keyIterator.remove();
           }
       }
    }
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017-06-23 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Channel通道
    • 通道的数据复制
    • Selector选择器
      • 关键对象
        • 监听注册
          • 例子
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档