• java.nio.ByteBuffer的flip、rewind和compact几个方法的区分使用


     

    java.nio.ByteBuffer的flip、rewind和compact几个方法的区分使用

    java.nio.ByteBuffer

    Capacity 缓冲区最大容量
    Limit 当前最大使用量,或者说是有效数据的EOF位置。
    Position 指向当前位置的指针

    Capacity 缓冲区最大容量 
    Limit 当前最大使用量,或者说是有效数据的EOF位置。

    Position 指向当前位置的指针

    假设一个缓冲区容量是10,开始指针指向0,即position=0。 
    然后写入6个字节数据,写完后,下标0、1、2、3、4、5有数据, 
    指针指向6,即当前position=6。 
    此时,用limit(6)方法将当前位置设为EOF位置。 
    那么,读数据的时候,读到EOF位置就结束了。

    下标超过的话,会报错java.nio.BufferUnderflowException

    clear(),只是把指针移到位置0,并没有真正清空数据。 
    flip(),当前位置设置为EOF,指针指向0. 
    rewind,指针指向0. 
    compact(),压缩数据。比如当前EOF是6,当前指针指向2 
    (即0,1的数据已经写出了,没用了), 
    那么compact方法将把2,3,4,5的数据挪到0,1,2,3的位置, 
    然后指针指向4的位置。这样的意思是,从4的位置接着再写入数据。

    写完后,把指针挪到0,再写出,然后再compact(),如此反复……

    buf.clear(); // 清空一下,准备 
    for (;;) { 
    if (in.read(buf) < 0 && !buf.hasRemaining()) 
    break; // 没有读入数据了,并且buffer里没有剩余数据了 
    buf.flip(); //当前位置设置为EOF,指针挪到0 
    out.write(buf); //写出数据,即读取buffer的数据 
    buf.compact(); // write方法可能只写出了部分数据,buffer里还有剩余。 
    //压缩一下,把后一段的数据挪到前面。指针也挪到有效数据的后一位。

    }

    下面是一段测试小代码,有助于熟悉各方法:

    import java.nio.ByteBuffer;
    
    
    public class ByteBufferTest {
    
        public static void main(String[] args) {
    
            //10个字节大小
            ByteBuffer buffer = ByteBuffer.allocate(10);
    
            //容量是10,EOF位置是10,初始位置也是0
            v(buffer.capacity());
            v(buffer.limit());
    
            //输出看看,输出是10个0
            printBuffer(buffer);
    
            //此时,指针指向位置10,已经是最大容量了。
            //把指针挪回位置1
            buffer.rewind();
    
            //写操作,指针会自动移动
            buffer.putChar('a');
            v(buffer.position()); //指针指向2
            buffer.putChar('啊');
            v(buffer.position()); //指针指向4
    
            //当前位置设置为EOF,指针挪回位置1
            //相当于下面两句:
            //buffer.limit(4);
            //buffer.position(0); 
            buffer.flip();
    
            //输出前4个字节看看,输出是0 61 55 4a
            printBuffer(buffer);
    
            //指针挪到位置1,压缩一下
            //输出是61 55 4a 4a 0 0 0 0 0 0
            //compact方法会把EOF位置重置为最大容量,这里就是10
            buffer.position(1);
            buffer.compact();
            printBuffer(buffer);
    
            //注意当前指针指向3,继续写入数据的话,就会覆盖后面的数据了。
            v(buffer.position());
    
        }
    
        /**
         * 输出buffer内容.
         */
        public static void printBuffer(ByteBuffer buffer){
    
            //记住当前位置
            int p = buffer.position();
    
            //指针挪到0
            buffer.position(0);
    
            //循环输出每个字节内容
            for(int i=0;i<buffer.limit();i++){
                byte b = buffer.get(); //读操作,指针会自动移动
                v(Integer.toHexString(b));
            }
    
            //指针再挪回去
            buffer.position(p);
    
            //本想用mark()和reset()来实现。
            //但是,它们貌似只能正向使用。
            //如,位置6的时候,做一下Mark,
            //然后在位置10(位置要大于6)的时候,用reset就会跳回位置6.
    
            //而position(n)这个方法,如果之前做了Mark,但是Mark位置大于新位置,Mark会被清除。
            //也就是说,做了Mark后,只能向前跳,不能往回跳,否则Mark就丢失。
            //rewind()方法,更干脆,直接清除mark。
            //flip()方法,也清除mark
            //clear()方法,也清除mark
            //compact方法,也清除mark
    
            //所以,mark方法干脆不要用了,自己拿变量记一下就完了。
        }
    
        public static void v(Object o){
            System.out.println(o);
        }
    
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88

    原文

     
  • 相关阅读:
    Android-监听操作系统短信
    Android-Observer(内容观察者)
    Android-ContentProvider读取/新增/操作系统联系人数据
    Android-ContentProvider原理图
    Android-ContentProvider-UriMatcher
    Android-ListView-CursorAdapter
    Android-ListView-SimpleCursorAdapter
    openssl可以实现:秘钥证书管理、对称加密和非对称加密
    网址收藏
    php 通用数据库类
  • 原文地址:https://www.cnblogs.com/handsome1013/p/7680219.html
Copyright © 2020-2023  润新知