欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Java NIO中的Buffer类

程序员文章站 2022-05-10 13:02:37
Buffer,即缓冲区,用于批量读写数据 Buffer是一个抽象类,基本数据类型都有实现类:XxxBuffer,比如ByteBuffer、CharBuffer、IntBuffer、DoubleBuffer等。 Buffer更像一个容器,用于盛装数据,可以从数据源读取数据,放在Buffer里,也可以从 ......

 

buffer,即缓冲区,用于批量读写数据

 

buffer是一个抽象类,基本数据类型都有实现类:xxxbuffer,比如bytebuffer、charbuffer、intbuffer、doublebuffer等。

 

buffer更像一个容器,用于盛装数据,可以从数据源读取数据,放在buffer里,也可以从buffer中取出数据来用。

 

 

buffer中的4个概念:

  • capacity     容量,此buffer的大小
  • limit      界限,limit是一个下标(索引),limit及以后的数据既不能读,也不能写
  • position      记录指针,记录当前读写到的位置
  • mark      标记。读写的时候,可在某处做一个标记,调用reset()方法可将记录指针重置到此mark处。

 

 

 

buffer使用步骤:

(1)创建buffer对象

static  xxxbuffer  allocate(int  capacity)      //静态方法,返回该类对应的buffer对象

1 //创建一个容量为10的charbuffer对象,一次最多可装10个char
2         charbuffer charbuffer=charbuffer.allocate(10);

 

 

(2)往buffer中放入数据,可使用put()往buffer中放入数据,也可以从channel中获取数据。

1  //xxxbuffer有多个重载的put()方法,但只能放入该种类型的数据。
2         charbuffer.put(char c);   //未指定index的,都是依次放置。一个萝卜一个坑,如果坑中有萝卜,就往后放。往坑中放萝卜时,记录指针会指向这个坑,放完后,记录指针会自动指向下一个坑。
3         charbuffer.put(int index,char c);   //在指定的坑中放萝卜
4         charbuffer.put(char[]  src);  //放在多个坑中,一个坑一个char
5         charbuffer.put(string str);  //放在多个坑中,一坑一个char
6         charbuffer.put(charbuffer src);  //把其他charbuffer中的所有萝卜都copy一份,放到这个charbuffer中来,一坑一个char

 

 

(3)数据放置完毕后,调用flip()方法,此方法会将limit设置为position(记录指针)的值,并将position(记录指针)的值置为0。这就标明了可读写的数据区间。

    说明:数据放置完毕后,position(记录指针)是指向最后一个萝卜后面的那个坑的。

1 charbuffer.flip();

Java NIO中的Buffer类

现在,buffer做好了输出数据的准备。

 

 

(4)从buffer中取出数据,并使用。

1      charbuffer.get();   //取一个萝卜。从前往后取,只取一个。
2      charbuffer.get(int index);   //取指定位置上的萝卜
3      //这里的取是指取出副本,并不是真的把萝卜从坑里拿出来,萝卜还是在这个坑里,不会变。

 

 

(5)当buffer中的数据都用完了,不需要再保存时,就可以调用clear()清空这个buffer,这样,每个坑都是空的了,又可以装入新的数据了。

1      charbuffer.clear();

 

 

 

示例:

 1 //创建buffer对象
 2         charbuffer charbuffer=charbuffer.allocate(10);
 3 
 4         //放入数据
 5         charbuffer.put("abcd");
 6 
 7         //调整指针,准备好使用数据
 8         charbuffer.flip();
 9 
10         //从buffer中取出数据来使用
11         system.out.println(charbuffer.get());  //a
12         system.out.println(charbuffer.get(2));  //取第三个,c
13         system.out.println(charbuffer.get());  //b
14 
15         //好啦,这批数据搞定了,不再用了,清空buffer,准备好下次装入数据
16         charbuffer.clear();
17         
18         //装入下一批数据
19         charbuffer.put('a');
20 
21         //.........

 

观察上面的输出结果,调用get()获取值后,记录指针会自动指向下一个坑。调用get(int  index)获取值,记录指针并不会受到影响,还是在原来的位置。

 

 

 

buffer类的其他常用方法:

  • int  capacity()    //返回容量
  • boolean   hasremaining()    //判断是否还有元素可供处理(position、limit之间是否还有萝卜)
  • int remaining()    //还有多少个元素未处理
  • int  limit()     //返回limit的位置
  • limit(int  newlimit)    //重新设置limit(以新buffer的形式返回,但原buffer的limit会改变)
  • int position()   //返回当前记录指针的位置
  • position(int  newposition)    //重置position的位置
  • mark()    //在当前position的位置做一个标记
  • reset()   //转到标记处,即将position指向mark处
  • rewind()   //将position重置为0,取消设置的mark,即从头开始。

 

 

 

通过 allocate() 创建的buffer是普通buffer。

bytebuffer提供了 allocatedirect()  来创建直接buffer,直接buffer读取数据的效率很高,但创建成本很高,适合用于创建生存期较长的buffer。一般情况用普通buffer即可。

只有bytebuffer类能创建直接buffer。