package me.test.jdk.java.nio;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
/**
* 测试 Buffer
* 0 <= mark <= position <= limit <= capacity
* <p>
* limit 仅仅在读取模式中有意义,代表可读取范围的最大边界。
* 在写入模式时, 默认均为 capacity。
* <p>
* CharBuffer#toString() 仅仅在读取模式时才有意义,返回值为未读取的数据。
* <p>
* 默认/clear/compact 进入待写入模式
* flip 进入待读取模式
*/
public class BufferTest {
public static void main(String[] args) throws IOException, NoSuchFieldException, IllegalAccessException {
// 默认: 待写入状态
CharBuffer buf = CharBuffer.allocate(10);
print(" 1", buf);
buf.put("abc");
print(" 2", buf);
buf.put("123");
print(" 3", buf);
buf.flip();
print(" 4", buf);
// 假设在这里读取了4个字符
System.out.println(buf.get());
System.out.println(buf.get());
System.out.println(buf.get());
System.out.println(buf.get());
print(" 5", buf);
buf.mark();
print(" 6", buf);
System.out.println(buf.get());
System.out.println(buf.get());
print(" 7", buf);
buf.reset();
print(" 8", buf);
// 将残留的未读取的数据放到 开头, 进入待写入状态。
buf.compact();
print(" 9", buf);
buf.put("xyz");
print("10", buf);
// 清空缓存, 进入带写入模式。
buf.clear();
print("10", buf);
}
static void print(String tag, CharBuffer buf) throws NoSuchFieldException, IllegalAccessException {
Field markField = Buffer.class.getDeclaredField("mark");
markField.setAccessible(true);
int m = (int) markField.get(buf);
// 获取内部字符数组的所有内容
int oldLimt = buf.limit();
buf.limit(buf.capacity());
char[] b = new char[buf.capacity()];
for (int i = 0; i < buf.capacity(); i++) {
b[i] = buf.get(i);
}
buf.limit(oldLimt);
char[] content = new char[buf.limit() - buf.position()];
for (int i = 0; i < content.length; i++) {
content[i] = buf.get(buf.position() + i);
}
System.out.printf("[%s] : mark/position/limit/capacity : (remaining) = %2d/%2d/%2d/%2d : (%2d) " +
": %s, toString()=%10s, content=%10s%n",
tag,
m,
buf.position(),
buf.limit(),
buf.capacity(),
buf.remaining(),
String.valueOf(b),
buf.toString(),
String.valueOf(content));
}
}