相关文章推荐
耍酷的跑步鞋  ·  ios ...·  4 天前    · 
痴情的铁链  ·  ByteBuffer中flip、mark、r ...·  4 天前    · 
谈吐大方的香菜  ·  idea 错误: ...·  1 年前    · 
活泼的芹菜  ·  echo | Microsoft Learn·  1 年前    · 

在解释以上方法之前我们需要了解ByteBuffer的几个参数:

  // Invariants: mark <= position <= limit <= capacity
    private int mark = -1;//标记位置,reset时需要
    private int position = 0;//当前读取
    private int limit;//读取的最大位置
    private int capacity;//buffer的容量

下面通过一个最简单的代码来解释,各个过程中上面参数的变化

//初始化一个长度为48的buffer
 ByteBuffer buffer = ByteBuffer.allocate(48);

此时 postion:0,limit48,mark:-1,capacity:48。下面的过程主要是postion、limit、mark会变化,capacity是容量不会变化。

  //将数据写入buffer
  buffer.put("123456".getBytes());

写入后ByteBuffer的参数变化如下图:

此时只有postion发生了变化,变成了6,因为我们写了6个字符。我们写入的数据就存储在0-5空间上

flip(): 接下来我们需要把写入的数据读取出来,这也是buffer的使用场景,那么我们需要调用flip()进行位置翻转

  buffer.flip();

执行flip()之后参数变化:

通过上图我们发现 position和limit发生了变化,postion变为:0,limit变为:6(这是flip()翻转之前的postion值)。那么此时我们就可以读取buffer中的数据了

        while(buffer.hasRemaining()){
            System.out.println((char) buffer.get());

 下面是buffer.hasRemaining()的代码

通过下面 hasRemaining()的源码我们可以看出,我们只能get()出0-5的位置上的数据,调用while()循环我们会依次打印出1、2、3、4、5、6 

    public final boolean hasRemaining() {
        return position < limit;

接下来我们说下mark()和reset()如何配合使用。

        举例一个使用场景我们能更好的理解,假设在读取读取4、5的时候我们需要做一些事务计算,比如g(f(4),f(5)),只要计算错误我们就需要重新读取计算,那么这时候我们就会用到mark()和reset()。

先贴出代码

      while(buffer.hasRemaining()){
            char c=(char)buffer.get();
            System.out.println(c);
            if(buffer.position()==3){
                buffer.mark();
            if(buffer.position()==4){
                a=f(c);
            if(buffer.position()==5){
                b=f(c);
                try {
                    System.out.println(g(a,b));
                    throw new Exception("主动抛出");
                } catch (Exception e) {
                    buffer.reset();

在postion=3时,执行mark()后,mark=3;抛出异常,catch里执行reset()后,postion=mark=3,重新读取4、5。dubug的视图就不再贴出来了。

通过上面论述,相信大家对ByteBuffer的重要参数已经有系统的了解,接下来rewind()和clear()就不难理解了。

以下是这两个方法的源码

rewind:重置mark并将potion设置到起始位置0

clear:重置ByteBuffer的重要参数

  public final Buffer rewind() {
        position = 0;
        mark = -1;
        return this;
   public final Buffer clear() {
        position = 0;
        limit = capacity;
        mark = -1;
        return this;
                                    Netty是当前非常流行的网络通讯框架,当程序对网络数据处理时,需要保证高并发和高可靠,底层就可以用Netty支撑。本套课程详细讲解了Netty核心技术点,同时进行底层机制和源码剖析,并编写了大量的应用实例。通过学习可以快速学习Netty的底层实现机制,熟练运用Netty解决网络高并发问题。Netty涉及内容很多(比如:设计模式、数据结构、并发、同步、异步,阻塞等),目前网上的Netty课程不多,且普遍讲解晦涩难懂,内容浅尝辄止,导致很多学习者只知道Netty的核心组件,但不知道怎么使用到项目之。本课程针对上述问题,有针对性的进行了升级:(1) 授课方式采用图解+源码分析的方式,让课程生动好理解;(2)除了系统的讲解,还对Netty的核心技术进行了源码剖析(包括: 心跳(heartbeat)服务、EventLoop源码、任务提交到异步线程池、Netty启动过程源码)。(3)protobuf ,掌握物联网开发 ,netty集群架构,掌握IM聊天项目,掌握IM架构知识 
我在网上搜索了很多,大部分都是说针对mark、limit、capacity、position 标志量来解释的,ok!我想补充一下,从如何应用的方面来说明其含义。 
1、有一个文件共有20个字符: 
    abcdefghijklmnopqrst 
2、我们声明一个char[15] buffer 大小的字符数组 
Java代码
   for(readChar(buffer...
                                    3、如果想要获取元素,就需要把 position 索引移动到开始位置,可以调用 flip() 方法,此时还会把 limit 赋值成 position 原来写入的位置,然后调用 get() ,position 就会往后移动1次,也就是 +1 操作,最后你最大只能读取。总结:allocate(1024) 方法开辟空间的代码就是将 ByteBuffer 的 limit 和 position 两个变量都设置成了 Capcity 容量大小,都是 1024 个字节大小。可以发现是从数组获取元素,索引就是。
public static void main(String[] args) {
        try (FileChannel channel = new FileInputStream("data.txt").getChannel()){
            // 定义缓冲区 allocate分配大小
            ByteBuffer buffer = ByteBuffer.allocate(10);
            while(tr
前一篇文章我们介绍了Android直播视频技术的基础大纲知识,这里就开始一一讲解各个知识点,首先主要来看一下视频直播的一个重要的基础核心类:ByteBuffer,这个类看上去都知道了,是字节缓冲区处理字节的,这个类的功能非常强大,也在各个场景都有用到,比如网络数据底层处理,特别是结合网络通道信息处理的时候,还有就是后面要说到的OpenGL技术也要用到,当然在视频处理也是很重要的,
                                    java.nio.ByteBuffer1. ByteBuffer的参数position、limit、capacity、mark含义:position:表示当前指针的位置(下一个要操作的数据元素的位置)limit:表示当前数组最大的使用量,即有效位置的EOF位置(缓冲区数组不可操作的下一个元素的位置,limit<=capacity)capacity:表示缓冲区最大容量(缓冲区数据的总长度)...
                                    java.nio.ByteBuffer类的rewind()方法用于倒带此缓冲区。位置设置为零,标记被丢弃。假设已正确设置了限制,请在序列channel-write或get操作之前调用此方法。调用此方法既不会更改,也不会丢弃标记的值。用法:public ByteBuffer rewind()返回值:此方法返回此缓冲区。下面是说明rewind()方法的示例:范例1:// Java program to...
                                    转载自:http://www.blogjava.net/sdjxsgb/archive/2013/06/18/400703.html
对缓冲区的读写操作首先要知道缓冲区的下限、上限和当前位置。下面这些变量的值对Buffer类的某些操作有着至关重要的作用: 
limit:所有对Buffer读写操作都会以limit变量的值作为上限。 position:代表对缓冲区进行读写时,当前游标的位置。