翻译为缓冲,是一块可以读写的区域。

思考:没有buffer之前的读写。
方法抽象方法
//是否只读
    public abstract boolean isReadOnly();
	//判断有没有数组
    public abstract boolean hasArray();
	//返回数组
    public abstract Object array();
    //返回数组偏移
    public abstract int arrayOffset();
	//是否是直接缓冲区
    public abstract boolean isDirect();
    //切分
    public abstract Buffer slice();
    //切分
    public abstract Buffer slice(int index, int length);
	//复制一个buffer
    public abstract Buffer duplicate();
    //
    abstract Object base();   构造函数
Buffer(long addr, int cap, MemorySegmentProxy segment) {this.address = addr;
        this.capacity = cap;
        this.segment = segment;
    }
    
    Buffer(int mark, int pos, int lim, int cap, MemorySegmentProxy segment) {   // package-private
        if (cap< 0)
            throw createCapacityException(cap);
        this.capacity = cap;
        this.segment = segment;
        limit(lim);
        position(pos);
        if (mark >= 0) {if (mark >pos)
                throw new IllegalArgumentException("mark >position: ("
                                                   + mark + ">" + pos + ")");
            this.mark = mark;
        }
    }普通方法
在这里插入代码片字段
static final Unsafe UNSAFE = Unsafe.getUnsafe();
    
    static final ScopedMemoryAccess SCOPED_MEMORY_ACCESS = ScopedMemoryAccess.getScopedMemoryAccess();
    static final int SPLITERATOR_CHARACTERISTICS =
        Spliterator.SIZED | Spliterator.SUBSIZED | Spliterator.ORDERED;
    private int mark = -1;
    private int position = 0;
    private int limit;
    private int capacity;
    
    long address;
    
    // Used by buffers generated by the memory access API (JEP-370)
    final MemorySegmentProxy segment;
常见类型的缓冲

public abstract class ByteBuffer
    extends Buffer
    implements Comparable{} ByteBuffer是抽象类无法直接实例化,可以通过allocate等方法返回实例。
allocate
public static ByteBuffer allocate(int capacity) {if (capacity< 0)
            throw new IllegalArgumentException();
        return new HeapByteBuffer(capacity, capacity);
    }allocateDirect
public static ByteBuffer allocateDirect(int capacity) {return new DirectByteBuffer(capacity);
    }ByteBuffer 分为HeapByteBuffer和DirectByteBuffer两种,翻译成人话就是堆字节缓冲和直接字节缓冲,第二种不受 JVM 控制。
ByteBuffer hbb = ByteBuffer.allocate(1024);
        ByteBuffer dbb = ByteBuffer.allocateDirect(1024);在后面的介绍中,hbb代指 JVM 缓冲区,dbb代指直接缓冲区。
HeapByteBuffer DirectByteBuffer 常见方法 allocate下面对 allocate 的调用链路参数进行分析。
public static ByteBuffer allocate(int capacity) {if (capacity< 0)
            throw new IllegalArgumentException();
        //capacity >= 0
        return new HeapByteBuffer(capacity, capacity);
    }cap = lim = capacity,由 HeapByteBuffer 构造函数调用 super
HeapByteBuffer(int cap, int lim) {   
        super(-1, 0, lim, cap, new byte[cap], 0);
    }mark = -1
pos = 0
lim = cap
cap = cap
hb = new byte[cap]
offset = 0
ByteBuffer(int mark, int pos, int lim, int cap,  
                 byte[] hb, int offset)
    {super(mark, pos, lim, cap); //-1,0,cap,cap
        this.hb = hb; //new byte[cap]
        this.offset = offset; //0
    }hb字节数组和offset 偏移量为 ByteBuffer 字段。
mark = -1
pos = 0
lim = cap
cap = cap
Buffer(int mark, int pos, int lim, int cap) {	//判断多余 cap >0     
        if (cap< 0)
            throw new IllegalArgumentException("Negative capacity: " + cap);  
        this.capacity = cap; // 1
        limit(lim); //2
        position(pos); //3 
        //汇总分析的参数 mark = -1,pos = 0
        if (mark >= 0) {if (mark >pos)
                throw new IllegalArgumentException("mark >position: ("
                                                   + mark + ">" + pos + ")");
            this.mark = mark;
        }
    }核心代码表示为1,2,3的部分。
public final Buffer limit(int newLimit) {// newLimit = lim = cap
        if ((newLimit >capacity) || (newLimit< 0))
            throw new IllegalArgumentException();
        limit = newLimit; //limit = newLimit = lim = cap
        if (position >limit) position = limit; // position = 0 limit = cap
        if (mark >limit) mark = -1; // mark = -1
        return this;
    }public final Buffer position(int newPosition) {// newPosition = pos = pos = 0
        if ((newPosition >limit) || (newPosition< 0))
            throw new IllegalArgumentException();
        position = newPosition; // position =  newPosition = pos = pos = 0
        if (mark >position) mark = -1;
        return this;
    }所以经过这一串构造函数后,buffer中的值分别为
java.nio.HeapByteBuffer[pos=0 lim=1024 cap=1024]pos = 位置,lim = 限制,cap = 容量,大值。
allocateDirectpublic static ByteBuffer allocateDirect(int capacity) {return new DirectByteBuffer(capacity);
    }DirectByteBuffer(int cap) {//cap =  capacity
    	//调用链路
        super(-1, 0, cap, cap);
       	//
        boolean pa = VM.isDirectMemoryPageAligned();
        int ps = Bits.pageSize();
        long size = Math.max(1L, (long)cap + (pa ? ps : 0));
        Bits.reserveMemory(size, cap);
        long base = 0;
        try {	//unsafe 分配内存空间
            base = unsafe.allocateMemory(size);
        } catch (OutOfMemoryError x) {Bits.unreserveMemory(size, cap);
            throw x;
        }
        unsafe.setMemory(base, size, (byte) 0);
        if (pa && (base % ps != 0)) {// Round up to page boundary
            address = base + ps - (base & (ps - 1));
        } else {address = base;
        }
        cleaner = Cleaner.create(this, new Deallocator(base, size, cap));
        att = null;
    }MappedByteBuffer(int mark, int pos, int lim, int cap) {// package-private
        super(mark, pos, lim, cap);
        this.fd = null;
    }ByteBuffer(int mark, int pos, int lim, int cap) {// package-private
        this(mark, pos, lim, cap, null, 0);
    }ByteBuffer(int mark, int pos, int lim, int cap,   // package-private
                 byte[] hb, int offset)
    {super(mark, pos, lim, cap);
        this.hb = hb;
        this.offset = offset;
    }Buffer(int mark, int pos, int lim, int cap) {   // package-private
        if (cap< 0)
            throw new IllegalArgumentException("Negative capacity: " + cap);
        this.capacity = cap;
        limit(lim);
        position(pos);
        if (mark >= 0) {if (mark >pos)
                throw new IllegalArgumentException("mark >position: ("
                                                   + mark + ">" + pos + ")");
            this.mark = mark;
        }
    }调用过程不再赘述,跟 allocate 链路差不多,区别是使用 unsafe 进行内存分配和其他的操作。
flip 翻转public final Buffer flip() {limit = position;
        position = 0;
        mark = -1;
        return this;
    }案例
ByteBuffer hbb = ByteBuffer.allocate(1024);
        System.out.println(hbb.toString());
        hbb.flip();
        System.out.println(hbb.toString());输出
java.nio.HeapByteBuffer[pos=0 lim=1024 cap=1024]
java.nio.HeapByteBuffer[pos=0 lim=0 cap=1024]public final boolean hasRemaining() {return position< limit;
    }position< limit 代表有剩余,position = limit 代表空间已经满了
clear 清除public final Buffer clear() {position = 0;
        limit = capacity;
        mark = -1;
        return this;
    }将buffer三个指针位置重置。
gethbb
final byte[] hb;    
    public byte get() {return hb[ix(nextGetIndex())];
    }dbb
public byte get() {return ((unsafe.getByte(ix(nextGetIndex()))));
    }public ByteBuffer asReadOnlyBuffer() {return new HeapByteBufferR(hb, this.markValue(), this.position(), this.limit(),
         this.capacity(), offset);
 }创建5个容量的buffer,依次将i放进去,翻转buf,依次读出来。
public class byteBuffer02 {public static void main(String[] args) {ByteBuffer buffer = ByteBuffer.allocate(5);
        for (byte i = 0; i< buffer.capacity(); i++) {buffer.put(i);
        }
        buffer.flip();
        while (buffer.hasRemaining()) {System.out.println(buffer.get());
        }
    }
}public class ByteBuffer03 {public static void main(String[] args) {ByteBuffer bb = ByteBuffer.allocate(64);
        bb.putInt(100);
        bb.putLong(9);
        bb.putChar('a');
        bb.putShort((short) 4);
        bb.flip();
        System.out.println("----");
        System.out.println(bb.getInt());
        System.out.println(bb.getLong());
        System.out.println(bb.getChar());
        System.out.println(bb.getShort());
    }
}public class ByteBuffer04 {public static void main(String[] args) {ByteBuffer b1 = ByteBuffer.allocate(64);
        ByteBuffer b2 = b1.asReadOnlyBuffer();
        b1.putInt(5);
        b2.putInt(5);
    }
}深入浅出java.nio.MappedByteBuffer
Channel 通道实现
源码
public interface Channel extends Closeable {//是否开启
    public boolean isOpen();
    //关闭
    public void close() throws IOException;
}static File file = new File("D://a.txt");RandomAccessFile raf = new RandomAccessFile(file, "rw");
        FileChannel fc = raf.getChannel();FileOutputStream fos = new FileOutputStream(file);
        FileChannel fc2 = fos.getChannel();      FileChannel fc3 = FileChannel.open(null, null);将 uuid 读出来
public class ReadFileUid {static File file = new File("D://a.txt");
    public static void main(String[] args) throws Exception {ByteBuffer bf = ByteBuffer.allocate(1024);
        try (RandomAccessFile raf = new RandomAccessFile(file, "rw");
             FileChannel fc = raf.getChannel()) {int read = fc.read(bf);
            System.out.println(read);
            System.out.println(bf);
            bf.flip();
            System.out.println(bf);
            byte[] bytes = new byte[bf.limit()];
            bf.get(bytes);
            System.out.println(bf);
            System.out.println(Arrays.toString(bytes));
            String str = new String(bytes, StandardCharsets.UTF_8);
            System.out.println(str);
        }
    }
}输出
36
java.nio.HeapByteBuffer[pos=36 lim=1024 cap=1024]
java.nio.HeapByteBuffer[pos=0 lim=36 cap=1024]
java.nio.HeapByteBuffer[pos=36 lim=36 cap=1024]
[54, 51, 51, 53, 98, 102, 53, 97, 45,
99, 57, 100, 54, 45, 52, 53, 51, 99,
45, 98, 57, 99, 98, 45, 102, 50, 52,
102, 56, 97, 54, 101, 98, 50, 99, 50]
6335bf5a-c9d6-453c-b9cb-f24f8a6eb2c2将 uuid 写到文件中
public class WriteFileUid {static File file = new File("D://a.txt");
    public static void main(String[] args) throws Exception {ByteBuffer bf = ByteBuffer.allocate(1024);
        try (RandomAccessFile raf = new RandomAccessFile(file, "rw");
             FileChannel fc = raf.getChannel()) {String uuid = UUID.randomUUID().toString();
            System.out.println(uuid);
            byte[] bytes = uuid.getBytes(StandardCharsets.UTF_8);
            System.out.println(Arrays.toString(bytes));
            System.out.println(bf);
            bf.put(bytes);
            System.out.println(bf);
            bf.flip();
            System.out.println(bf);
            int write = fc.write(bf);
            System.out.println(write);
        }
    }
}efdd8059-4f47-42e9-b9f9-aadd4a324309
[101, 102, 100, 100, 56, 48, 53, 57, 45, 52, 102, 52, 55,
 45, 52, 50, 101, 57, 45, 98, 57, 102, 57, 45, 97, 97,
  100, 100, 52, 97, 51, 50, 52, 51, 48, 57]
java.nio.HeapByteBuffer[pos=0 lim=1024 cap=1024]
java.nio.HeapByteBuffer[pos=36 lim=1024 cap=1024]
java.nio.HeapByteBuffer[pos=0 lim=36 cap=1024]
36你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧
网页名称:深入浅出javanio-创新互联
当前地址:http://www.jxjierui.cn/article/dgpsgc.html

 建站
建站
 咨询
咨询 售后
售后
 建站咨询
建站咨询 
 