NIO学习笔记(2)-- Buffer的浅拷贝和深拷贝

NIO学习笔记(2)-- Buffer的浅拷贝和深拷贝

1. Buffer的7种类型

ByteBuffer, CharBuffer, ShortBuffer, IntBuffer, LongBuffer, FloatBuffer, DoubleBuffer

由于ByteBuffer类型比较特殊,他能其他的所有类型(理解起来也不复杂,因为底层存的类型就是Byte)

public class NioTest {
    public static void main(String[] args) {
        ByteBuffer buffer = ByteBuffer.allocate(64);
        buffer.putInt(15);
        buffer.putLong(500000000L);
        buffer.putDouble(14.123456);
        buffer.putChar('你');
        buffer.putShort((short)2);
        
        buffer.flip();

        System.out.println(buffer.getInt());
        System.out.println(buffer.getLong());
        System.out.println(buffer.getDouble());
        System.out.println(buffer.getChar());
        System.out.println(buffer.getShort());
        System.out.println(buffer.getChar());
    }
}

2. Buffer 的浅度拷贝

public class NioTest {
    public static void main(String[] args) {
        ByteBuffer buffer = ByteBuffer.allocate(10);

        for(int i = 0; i < buffer.capacity(); ++i) {
            buffer.put((byte)i);
        }

        // 设置从第三位开始操作 并且只能操作到第七位
        buffer.position(2);
        buffer.limit(6);
	    // 创建一个和buffer共享数据的缓存
        ByteBuffer sliceBuffer = buffer.slice();

        for(int i = 0; i < sliceBuffer.capacity(); ++i) {
            byte b = sliceBuffer.get(i);
            b *= 2;
            sliceBuffer.put(i, b);
        }

        buffer.position(0);
        buffer.limit(buffer.capacity());

        while(buffer.hasRemaining()) {
            System.out.println(buffer.get());
        }
        
        System.out.println(" ---------------- ");

        while (sliceBuffer.hasRemaining()) {
            System.out.println(sliceBuffer.get());
        }
        
        
    }

}
/** 运行结果如下:
 * 0
 * 1
 * 4
 * 6
 * 8
 * 10
 * 6
 * 7
 * 8
 * 9
 *  ---------------- 
 * 4
 * 6
 * 8
 * 10
 */

3.Buffer 的深度拷贝

public class NioTest {
    public static void main(String[] args) {
        ByteBuffer buffer = ByteBuffer.allocate(10);

        for (int i = 0; i < buffer.capacity(); ++i) {
            buffer.put((byte) i);
        }

        buffer.position(2);
        buffer.limit(6);

        ByteBuffer sliceBuffer = buffer.slice();

        for (int i = 0; i < sliceBuffer.capacity(); ++i) {
            byte b = sliceBuffer.get(i);
            b *= 2;
            sliceBuffer.put(i, b);
        }

        buffer.position(0);
        buffer.limit(buffer.capacity());
        
        while (sliceBuffer.hasRemaining()) {
            System.out.println(sliceBuffer.get());
        }

        ByteBuffer copyBuffer = clone(sliceBuffer);

        for (int i = 0; i < copyBuffer.limit(); i++) {
            byte b = sliceBuffer.get(i);
            b *= 2;
            copyBuffer.put(i, b);
        }

        System.out.println(" ---------------- ");

        while (copyBuffer.hasRemaining()) {
            System.out.println(copyBuffer.get());
        }
    }

    // 深度拷贝方法
    public static ByteBuffer clone(ByteBuffer original) {
        ByteBuffer clone = ByteBuffer.allocate(original.capacity());
        // 使缓冲区准备好重新读取已经包含的数据:它保持限制不变,并将位置设置为零。
        // 因为 put(buffer) 会在内部遍历buffer,如果不执行rewind,position值将不会被重置
        original.rewind();
        clone.put(original);
        original.rewind();	
        // 这个是将clone转换为读的这状态,否则将无法读取出数据
        clone.flip();
        return clone;
    }
}

4. 获取只读Buffer

我们可以将一个普通Buffer调用asReadOnlyBuffer方法返回一个只读Buffer,但是不能将只读Buffer 转换为一个只写Buffer.

public class NioTest {

    public static void main(String[] args) {
        ByteBuffer buffer = ByteBuffer.allocate(10);

        System.out.println(buffer.getClass());

        for (int i = 0; i < buffer.capacity(); ++i) {
            buffer.put((byte)i);
        }

        ByteBuffer readonlyBuffer = buffer.asReadOnlyBuffer();

        System.out.println(readonlyBuffer.getClass());

        readonlyBuffer.position(0);
	//	执行此行代码会报错,说明该buffer为只读,可能你会想为啥没有只写,如果只能写的话那将没有意义。
	// readonlyBuffer.put((byte)2);
    }
}

你可能感兴趣的:(netty,java,NIO,netty)