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);
}
}