• 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

  • 相关阅读:
    菜鸟版JAVA设计模式—从买房子看代理模式
    NTP工作机制及时间同步的方法
    Java工厂模式
    圣魔大战3(Castle Fantisia)艾伦希亚战记完美攻略
    对javabean的内省操作
    插入排序(insertion sort)
    中英文对照 —— 十二星座
    中英文对照 —— 十二星座
    数学归纳法的相关证明
    数学归纳法的相关证明
  • 原文地址:https://www.cnblogs.com/ivywenyuan/p/4833526.html
Copyright © 2020-2023  润新知