buffer的例子
@Test
public void test()
{
CharBuffer buffer = CharBuffer.allocate(8);
System.out.println("capacity:"+buffer.capacity());//输出8
System.out.println("limit:"+buffer.limit());//输出8
System.out.println("position:"+buffer.position());//输出0
buffer.put('a');
buffer.put('b');
buffer.put('c');
System.out.println("=====加入三个元素后======");
System.out.println("capacity:"+buffer.capacity());//输出8
System.out.println("limit:"+buffer.limit());//输出8
System.out.println("position:"+buffer.position());//输出3
//在进行读操作前调用 flip()方法 limit移动到position位置 把 position指针移动到0位置
buffer.flip();
System.out.println("=====调用flip方法后======");
System.out.println("position:"+buffer.position());//输出0
System.out.println("limit:"+buffer.limit());//输出3
//buffer.get()获取当前position指针的值 position+1
System.out.println("=====调用buffer.get()方法======");
System.out.println("输出:"+buffer.get());//输出a
System.out.println("输出:"+buffer.get());//输出b
System.out.println("当前position:"+buffer.position());//输出2
//buffer.clear() clear方法不是清空数据而是把position指针置0 limit置capacity 为下一次输入数据做准备
System.out.println("=====调用buffer.clear()方法======");
System.out.println("limit:"+buffer.limit());//输出8
System.out.println("position:"+buffer.position());//输出0
//get(index)按索引取值验证clear()是否删除数据
System.out.println("按索引取数据:"+buffer.get(2));//输出c 表明没有删除数据
}
输出
capacity:8
limit:8
position:0
=====加入三个元素后======
capacity:8
limit:8
position:3
=====调用flip方法后======
position:0
limit:3
=====调用buffer.get()方法======
输出:a
输出:b
当前position:2
=====调用buffer.clear()方法======
limit:3
position:2
按索引取数据:c
Channel的例子
从test.txt文件中读取内容输出到a.txt并将内容输出到控制台
@Test
public void test2()
{
File f = new File("src//NIO//test.txt");
try (
FileChannel inChannel = new FileInputStream(f).getChannel();
FileChannel outChannel = new FileOutputStream("src//NIO//a.txt").getChannel();
)
{
//将FileChannel中的数据全部映射成ByteBuffer
MappedByteBuffer buffer=inChannel.map(FileChannel.MapMode.READ_ONLY,0,f.length());
//在"src//NIO//a.txt"中写入数据
outChannel.write(buffer);//写入完成此时position==limit==capacity==f.length
System.out.println("文件长度:"+f.length());
System.out.println("capacity:"+buffer.capacity());
System.out.println("limit:"+buffer.limit());
System.out.println("position:"+buffer.position());
//调用clear()不删除数据 置position=0
buffer.clear();
Charset charset = Charset.forName("GBK");//创建解码器
//创建解码器哦
CharsetDecoder decoder = charset.newDecoder();
//使用解码器将ByteBuffer转换成CharBuffer
CharBuffer charBuffer = decoder.decode(buffer);
System.out.println("====输出测试文件内容=====");
System.out.println(charBuffer);
}
catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (IOException e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
测试文件内容为 :测试123asc
控制台输出:
文件长度:10
capacity:10
limit:10
position:10
====输出测试文件内容=====
测试123asc
从文件中读取数据
文件内容:测试123asc是的v是的是的分v三大城市的胜多负少的v大幅上厕所反射是是
//从文件中读取数据
@Test
public void test4()
{
File f = new File("src//NIO//test.txt");
try {
FileChannel inChannel = new FileInputStream(f).getChannel();
ByteBuffer buffer = ByteBuffer.allocate(50);
while(inChannel.read(buffer)!=-1)
{
//读入完毕将limit置为position 将position置为0准备读出数据
buffer.flip();
Charset charset = Charset.forName("GBK");//创建解码器
//创建解码器哦
CharsetDecoder decoder = charset.newDecoder();
//使用解码器将ByteBuffer转换成CharBuffer
CharBuffer charbuffer = decoder.decode(buffer);
System.out.println(charbuffer);
//读出完毕将position置0 limit值为capacity准备再次读入数据
buffer.clear();
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
控制台输出:
报错:当输入字节序列对于给定 charset 来说是不合法的,或者输入字符序列不是合法的 16 位 Unicode 序列时,抛出此经过检查的异常。说白了,会出现java.nio.charset.MalformedInputException异常,原因是“半个中文问题”。
首先我们删掉文件中的所有英文字符 GBK编码为2个字节我们将buffer容量改为2
控制台输出
测
试
是
的
是
的
是
的
分
三
大
城
市
的
胜
多
负
少
的
大
幅
上
厕
所
反
射
是
是
似
懂
非
懂
是
闪
电
风
暴
的
分
水
电
费
水
电
费
是
多
少
的
曾
多
次
到
市
场
上
的
出
生
地
符合预期每次读2个字节也就是一个字符
接着把容量改为16也就是一次输出8个字符
ByteBuffer buffer = ByteBuffer.allocate(16);
控制台输出
测试是的是的是的
分三大城市的胜多
负少的大幅上厕所
反射是是似懂非懂
是闪电风暴的分水
电费水电费是多少
的曾多次到市场上
的出生地
符合预期
参考资料:点击打开链接 疯狂Java讲义