1. Buffer 类是 java.nio 的构造基础。一个 Buffer 对象是固定数量的、数据的容器,其作用是一个存储器或者分段运输区。在这里,数据可被存储并在之后用于检索。缓冲区可以被写满或释放。对于每个非布尔类型的、原始数据类型都有一个缓冲区类,即 Buffer 的子类有:ByteBuffer、CharBuffer、DoubleBuffer、FloatBuffer、IntBuffer、LongBuffer 和 ShortBuffer,是没有 BooleanBuffer 之说的。尽管缓冲区作用于它们存储的原始数据类型,但缓冲区十分倾向于处理字节。
  2. Buffer及其子类都不是线程安全的,若多线程操作该缓冲区,则应通过同步来控制对该缓冲区的访问。
  3. 每个Buffer都有以下四个属性:
    (1) capacity:容量,缓冲区能够容纳的数据元素的最大数量。这一容量在缓冲区创建时被设定,且永远不能被改变
    (2) limit:上界,缓冲区的第一个不能被读或写的元素。缓冲区创建时,limit 的值等于 capacity 的值。假设 capacity = 1024,我们在程序中设置了 limit = 512,说明Buffer 的容量为 1024,但是从 512 之后既不能读也不能写,因此可以理解成,Buffer 的实际可用大小为 512
    (3) position:位置,下一个要被读或写的元素的索引。位置会自动由相应的 get() 和 put() 函数更新。 这里需要注意的是positon的位置是从0开始,比如,已经写入buffer 3个元素那那么position就是指向第4个位置,即position设置为3(数组从0开始计)
    (4) mark:标记,一个备忘位置。保存某个时刻的position指针的值,通过调用mark()实现,当mark被置为负值时,表示废弃标记。标记在设定前是未定义的(undefined)。使用场景是,假设缓冲区中有 10 个元素,position 目前的位置为 2(也就是如果get的话是第三个元素),现在只想发送 6 - 10 之间的缓冲数据,此时我们可以 buffer.mark(buffer.position());即把当前的 position 记入 mark 中,然后 buffer.postion(6);此时发送给 channel 的数据就是 6 - 10 的数据。发送完后,我们可以调用 buffer.reset() 使得 position = mark,因此这里的 mark 只是用于临时记录一下位置用的
    (5) position和limit之间的距离指定了可读/写的字节数
    (6) mark,position,limit,capacity大小关系:
 -1 <= mark <= position <= limit <= capacity0<= position <= limit <= capacity
  1. 常用的方法一:
    (1) clear(),把position设为0,把limit设为capacity,取消标记,一般在把数据写入Buffer前调用,Buffer中的数据并未清除,只是这些标记告诉我们可以从哪里开始往Buffer里写数据。如果Buffer中有一些未读的数据,调用clear()方法以后,数据将“被遗忘”,意味着不再有任何标记会告诉你哪些数据被读过,哪些还没有。源码如下:
    public final Buffer clear() {
    position = 0;
    limit = capacity;
    mark = -1;
    return this;
    }
    (2) compact(),如果Buffer中仍有未读的数据,且后续还需要这些数据,但是此时想要先写些数据,那么使用compact()方法。compact()方法将所有未读的数据拷贝到Buffer起始处。然后将position设到最后一个未读元素正后面。limit属性依然像clear()方法一样,设置成capacity。现在Buffer准备好写数据了,但是不会覆盖未读的数据。
    (3) flip(),把limit设为当前position,把position设为0,取消标记,一般在从Buffer中读取数据前调用。源码如下:
    public final Buffer flip() {
    limit = position;
    position = 0;
    mark = -1;
    return this;
    }
    (4) rewind(),把position设为0,limit不变,一般在把数据重写入Buffer前调用。源码如下:
    public final Buffer rewind() {
    position = 0;
    mark = -1;
    return this;
    }
    (5) hasRemaining(),当缓冲区至少还有一个元素时,返回true;
    (6) remaining(),position和limit之间字节个数;
    (7) reset(),将position的值还原成上次调用mark()方法后的position的值。源码如下:
    public final Buffer reset() {
    int m = mark;
    if (m < 0)
    throw new InvalidMarkException();
    position = m;
    return this;
    }

  2. 常用方法二:
    (1) allocate(),分配一个具有指定大小的底层数组,并将它包装到一个缓冲区对象中,用静态方法 allocate() 来分配缓冲区;
    (2) wrap(),将一个已有的byte数组包装出一个新的bytebuffer对象;
    (3) slice(),根据现有的缓冲区创建一个子缓冲区。也就是它创建一个新的缓冲区,新缓冲区与原来的缓冲区的一部分共享数据,子缓冲区和缓冲区 共享同一个底层数据数组,分片操作是根据当前position以及limit的值来确定的;
    (4) order(),返回ByteBuffer的字节序;

  3. 视图缓冲区,可以用ByteBuffer对象创建其他类型的缓冲区,新缓冲区共享原始ByteBuffer的全部或者部分内存,这样的缓冲区被叫做视图缓冲区,就是通过源缓冲区创建其他的基础数据类型的缓冲区,新缓冲区和源缓冲区共享数据,但各自维护自己的属性(capacity、limit、position、mark)。

  4. 使用Buffer读/写数据一般遵循以下四个步骤:
    (1) 写入数据到Buffer;
    (2) 调用flip()方法;
    (3) 从Buffer中读取数据;
    (4) 调用clear()方法或者compact()方法;

  5. 当向buffer写入数据时,buffer会记录下写了多少数据;一旦要读取数据,需要通过flip()方法将Buffer从写模式切换到读模式;在读模式下,可以读取之前写入到buffer的所有数据。一旦读完了所有的数据,就需要清空缓冲区,让它可以再次被写入。
    有两种方式能清空缓冲区:调用clear()或compact()方法。clear()方法会清空整个缓冲区。compact()方法只会清除已经读过的数据。任何未读的数据都被移到缓冲区的起始处,新写入的数据将放到缓冲区未读数据的后面。

JAVA基础 - BYTEBUFFER是什么?相关推荐

  1. java 基础--NIO(4)

          Java    NIO   1.     Java NIO(New IO)是从Java 1.4版本开始引入的一个新的IO API,可以替代标准的Java IO   API NIO与原来的I ...

  2. 面试可能遇到java基础知识

    1.面向对象的特征有哪些方面?  答:面向对象的特征主要有以下几个方面:  - 抽象:抽象是将一类对象的共同特征总结出来构造类的过程,包括数据抽象和行为抽象两方面.抽象只关注对象有哪些属性和行为,并不 ...

  3. java 基础知识(不定期更新)

    1.面向对象的特征有哪些方面? 抽象:抽象是将一类对象的共同特征总结出来构造类的过程,包括数据抽象和行为抽象两方面.抽象只关注对象有哪些属性和行为,并不关注这些行为的细节是什么. 继承:继承是从已有类 ...

  4. java基础知识面试题(41-95)

    41.日期和时间: - 如何取得年月日.小时分钟秒? - 如何取得从1970年1月1日0时0分0秒到现在的毫秒数? - 如何取得某月的最后一天? - 如何格式化日期? 答: 问题1:创建java.ut ...

  5. Java基础知识与集合部分面试题整理

    JAVA基础知识 一.JDK与JRE 1.JDK和JRE的区别 可从面向对象.主要作用和组成部分三方面对比.如下图所示: 2.JDK – Java Development Kit 1). 主要面向开发 ...

  6. 【Java基础】从Java语言层面理解BIO,NIO,AIO(二)

    文章目录 零.从网络层面理解BIO,NIO,AIO 一.相关概念 1.什么是socket? 2.IP地址(IP Address) 3.端口(Port) 4.协议(Protocol) 4.1.协议简介 ...

  7. JAVA基础个人总结,不喜勿喷

    文章目录 **Java基础语法** **计算机理论基础** **数据类型** 基本数据类型: 引用数据类型: **运算符** 位运算符 : 移位运算符 << : **流程控制**: 分支流 ...

  8. BTA 常问的 Java基础40道常见面试题及详细答案

    最近看到网上流传着,各种面试经验及面试题,往往都是一大堆技术题目贴上去,而没有答案. 为此我业余时间整理了,Java基础常见的40道常见面试题,及详细答案,望各路大牛,发现不对的地方,不吝赐教,留言即 ...

  9. java基础知识 整理

    1.面向对象的特征有哪些方面? 答:面向对象的特征主要有以下几个方面: - 抽象:抽象是将一类对象的共同特征总结出来构造类的过程,包括数据抽象和行为抽象两方面.抽象只关注对象有哪些属性和行为,并不关注 ...

最新文章

  1. python生成试卷制卷系统_Python 读写文件 小应用:生成随机的测验试卷文件
  2. 机器学习算法与技术简介
  3. RAC 实例 迁移到 单实例 -- 使用导出导入
  4. 如何给你的web项目加入log4net支持
  5. 四个使用this的典型应用
  6. Java中浮点数的基础知识
  7. omwin密立根油滴实验数据处理程序_大物实验报告更新啦~
  8. Linux的Nginx六:源码|安装
  9. 链表面试题2:编写代码,以给定值x为基准将链表分割成两部分,所有小于x的结点排在大于或等于x的结点之前
  10. How to remove replication in SyteLine V2
  11. 使用docker部署mysql主从复制集群
  12. 【动态规划】完全背包问题
  13. CommandLineRunner 和 ApplicationRunner 的区别
  14. 优雅的closesocket
  15. .NET中利用XML来自动生成代码策略
  16. 小强的HTML5移动开发之路(20)——HTML5 Web SQL Database
  17. 基于MicroPython实现ESP32+SSD1306的小恐龙游戏
  18. his软件测试文档,HIS系统各子系统功能描述
  19. 5G+如何改变社会--读书有感
  20. 【presto 】presto 新版本升级详情

热门文章

  1. 解决wampserver橙色变成绿色
  2. OpenGL ES _ 着色器_片断着色器详解
  3. disql连接上运行sql是显示未连接
  4. java毕业设计——基于java+JSP+sqlserver的Smart系统-题库及试卷管理模块设计与实现(毕业论文+程序源码)——学生信息管理系统模板2
  5. 视频大文件传输的演变:从“卷轴男孩”到自动化
  6. Android集成腾讯信鸽推送SDK
  7. 算法笔记(3)—— 快速 I/O 算法:快速输入算法、快速输出算法
  8. CAN总线与RS485的区别
  9. VB编程:While...Wend语句实例漂亮的星星-17
  10. matlab怎么显示特征脸,matlab表情识别 Matlab表情识别,特征脸[1 ]作为面部表情分类的方法 联合开发网 - pudn.com...