java的nio的缓冲区

  1. 什么是“流”

    所谓流就是有产出数据能力的东东(学名就是“数据源”,“输入流”)或者接收数据的能力的东东(学名就是“数据接收端”,“输出流”,通信里面一般把这种东西叫“信宿”吧),一个文件可读,那么它就有产出数据的能力;一个文件可写,那么它就有接收数据的能力。

    java下的InputStream就是"输入流"的最顶层类,OutputStream 就是“输出流”的最顶层类。

    其实这里名字有点混淆,因为:按说能产出数据的应该叫“输出***” ,能接收数据的应该叫“输入***” 。其实之所以按上面说的命名是因为,我们总是站在“内存”的角度上说的,你有产出数据的能力,那么你产出的数据应该“流入”到我内存里来,而你能接收数据,那我内存就把数据“输出”给你好啦。

  2. Buffer的存在
    java的nio里面有Buffer,这是个缓存器。缓冲器对于数据的高速I/O很关键。ByteBuffer是将数据移进移出通道的唯一方式(尽管你可以使用as***方法,利用视图缓冲器将基本类型数据移进移出ByteBuffer)

    在java里面这样做:输入流用.getChannel() 或者输出流.getChannel()方法获取通道,然后通道再和缓冲器交互,调用输入流的通道的read方法可以给缓冲器里放入数据,调用输出流的通道的write方法可以获取缓冲器里的数据。

    缓冲区有两个指示位置: postion(当前位置) 和limit(上限位置)

    当你要获取get() 缓冲区里的内容时,你需要上限位置设为当前位置,把当前位置设为0。 可以调用flip方法

    java api文档里这样写的:
     in.read(buf);      // 输入流给缓冲器里放入数据
     buf.flip();        // 缓冲器的“当前位置”和“上界位置”重置
     out.write(buf);    // 输出流读取刚刚输入流给缓冲器的数据

    个人感觉吧,缓冲器就是有两个指针的一段内存。

     还有rewind() 方法:它其实只是重置了“当前位置”,将当前位置重置为0,而上限位置保持不变

  3. ByteBuffer的静态方法wrap
    其实我一直不是很理解这个静态方法,因为往缓冲器里放东西直接put就好啦,干嘛需要这个方法呢?
    目前的理解是这样:
    使用put方法之前需要先allocate() 分配内存空间,但是wrap不需要,直接wrap即可。
     1         ByteBuffer bb =  ByteBuffer.allocate(1024);
     2         IntBuffer ib = bb.asIntBuffer(); 
     3         ib.put(new int[]{11,43,56,35,118,29});
     4         System.out.println("the third int is:"+ib.get(2));
     5         ib.put(2,78);
     6         ib.flip();//如果你不flip的话,输出结果就全是零,因为是当前位置之后读取的
     7         while(ib.hasRemaining()){
     8             System.out.println(ib.get());
     9         }
    10         String ss = "只是为了测试";
    11         ByteBuffer sbb;
    12         try {
    13             sbb = ByteBuffer.wrap(ss.getBytes("UTF-16"));//这里就直接wrap了,并不需要事先分配allocate出空间
    14             //sbb.flip();
    15             System.out.println(sbb.asCharBuffer());//输出结果是:?只是为了测试  不是想要的结果也
    16         } catch (UnsupportedEncodingException e) {
    17             // TODO Auto-generated catch block
    18             e.printStackTrace();
    19         }

     一般来说呢,allocate,put,flip,get搭配使用;wrap,rewind,get配合使用(因为你wrap分配的就是字节数组那么大的空间,所以直接rewind只改变当前位置即可,不需要改变limit位置,所以不用flip啦)


    Buffer有四个索引:position,limit,capacity,mark。上面已经说了两个。

未完待续

参考:http://cheng330301560.iteye.com/blog/1028820

原文地址:https://www.cnblogs.com/ivywenyuan/p/4833526.html