zoukankan      html  css  js  c++  java
  • 五、Java NIO Scatter / Gather

    所有文章

    https://www.cnblogs.com/lay2017/p/12901123.html

    正文

    在前面的文章中,我们默认了一个规则。就是默认了一个Channel对应了一个Buffer,它们之间的读写发生在一对一关系里。事实上,Channel是可以对应多个Buffer的,也就是一对多关系。

    当一个Channel向多个Buffer写入数据的时候,称作分散(Scatter)

    当一个Channel从多个Buffer读取数据的数据,称作聚集(Gather)

    分散读取(Scattering Read)

    分散读取意味着从一个Channel中读取数据到多个Buffer里面。如图:

     以下是示例代码

    ByteBuffer header = ByteBuffer.allocate(128);
    ByteBuffer body   = ByteBuffer.allocate(1024);
    
    ByteBuffer[] bufferArray = { header, body };
    
    channel.read(bufferArray);

    注意,示例中首先创建了两个Buffer:header、body,分别具备固定大小。header、body再放到一个array当中。Channel向Buffer读数据的时候入参是array。

    我们关注一个read方法的逻辑,read方法传入了两个Buffer。当第一个Buffer满了以后,才会开始往第二个Buffer填充数据。也就是说其内部是遍历Buffer来填充数据的,当前一个Buffer没有满的情况下是不会移动到下一个Buffer的。这意味着,分散读取到多个Buffer并不适用于大小是动态的。换句话说,如果header的大小不是固定的,那么使用过程中可能就会出现body的数据在header的Buffer中,这就造成了一些问题。所以分散读取到多个Buffer,需要Buffer大小相对固定。

    聚集写入(gathering write)

    聚集写入,是将多个Buffer的数据写入到一个Channel当中,如图

     以下是示例代码

    ByteBuffer header = ByteBuffer.allocate(128);
    ByteBuffer body   = ByteBuffer.allocate(1024);
    
    //write data into buffers
    
    ByteBuffer[] bufferArray = { header, body };
    
    channel.write(bufferArray);

    类似地,传入了多个Buffer。当write方法执行地时候,会按照顺序从Buffer中读入数据,并写入到Channel当中。不过和分散读不同地是,聚集写不需要Buffer固定大小。一个Buffer只要读完数据就会换下一个Buffer。

  • 相关阅读:
    Leetcode 58. 最后一个单词的长度 双指针
    Leetcode 125. 验证回文串 双指针
    拜托,大厂做项目可不简单!
    被问懵了:一个进程最多可以创建多少个线程?
    面对祖传屎山代码应该采用的5个正确姿势
    VUE代码格式化配置vetur、eslint、prettier的故事
    如何快速实现一个虚拟 DOM 系统
    NodeJS 进程是如何退出的
    [堆][启发式合并]luogu P3261 [JLOI2015]城池攻占
    [Trie][堆]luogu P5283 [十二省联考2019]异或粽子
  • 原文地址:https://www.cnblogs.com/lay2017/p/12905925.html
Copyright © 2011-2022 走看看