zoukankan      html  css  js  c++  java
  • ByteBuffer用法小结

    在 NIO中,数据的读写操作始终是与缓冲区相关联的.读取时信道(SocketChannel)将数据读入缓冲区,写入时首先要将发送的数据按顺序填入缓冲 区.缓冲区是定长的,基本上它只是一个列表,它的所有元素都是基本数据类型.ByteBuffer是最常用的缓冲区,它提供了读写其他数据类型的方法,且 信道的读写方法只接收ByteBuffer.因此ByteBuffer的用法是有必要牢固掌握的.

    1.创建ByteBuffer
    1.1 使用allocate()静态方法
        ByteBuffer buffer=ByteBuffer.allocate(256);
        以上方法将创建一个容量为256字节的ByteBuffer,如果发现创建的缓冲区容量太小,唯一的选择就是重新创建一个大小合适的缓冲区.

    1.2 通过包装一个已有的数组来创建
        如下,通过包装的方法创建的缓冲区保留了被包装数组内保存的数据.
        ByteBuffer buffer=ByteBuffer.wrap(byteArray);

        如果要将一个字符串存入ByteBuffer,可以如下操作:
        String sendString="你好,服务器. ";
        ByteBuffer sendBuffer=ByteBuffer.wrap(sendString.getBytes("UTF-16"));

    2.回绕缓冲区
      buffer.flip();
      这个方法用来将缓冲区准备为数据传出状态,执行以上方法后,输出通道会从数据的开头而不是末尾开始.回绕保持缓冲区中的数据不变,只是准备写入而不是读取.

    3.清除缓冲区
      buffer.clear();
      这个方法实际上也不会改变缓冲区的数据,而只是简单的重置了缓冲区的主要索引值.不必为了每次读写都创建新的缓冲区,那样做会降低性能.相反,要重用现在的缓冲区,在再次读取之前要清除缓冲区.

    4.从套接字通道(信道)读取数据
      int bytesReaded=socketChannel.read(buffer);
      执行以上方法后,通道会从socket读取的数据填充此缓冲区,它返回成功读取并存储在缓冲区的字节数.在默认情况下,这至少会读取一个字节,或者返回-1指示数据结束.

    5.向套接字通道(信道)写入数据
      socketChannel.write(buffer);
      此方法以一个ByteBuffer为参数,试图将该缓冲区中剩余的字节写入信道.

     

     

    -----------------------

     

    ByteBuffer俗称缓冲器, 是将数据移进移出通道的唯一方式,并且我们只能创建一个独立的基本类型缓冲器,或者使用“as”方法从 ByteBuffer 中获得。ByteBuffer 中存放的是字节,如果要将它们转换成字符串则需要使用 Charset , Charset 是字符编码,它提供了把字节流转换成字符串 ( 解码 ) 和将字符串转换成字节流 ( 编码) 的方法。

    private byte[] getBytes (char[] chars) {//将字符转为字节(编码)
       Charset cs = Charset.forName ("UTF-8");
       CharBuffer cb = CharBuffer.allocate (chars.length);
       cb.put (chars);
       cb.flip ();
       ByteBuffer bb = cs.encode (cb)
       return bb.array();
             }

    private char[] getChars (byte[] bytes) {//将字节转为字符(解码)
          Charset cs = Charset.forName ("UTF-8");
          ByteBuffer bb = ByteBuffer.allocate (bytes.length);
          bb.put (bytes);
          bb.flip ();
           CharBuffer cb = cs.decode (bb);
      
       return cb.array();
    }

    通 道也就是FileChannel,可以由FileInputStream,FileOutputStream,RandomAccessFile三个类来 产生,例如:FileChannel fc = new FileInputStream().getChannel();与通道交互的一般方式就是使用缓冲器,可以把通道比如为煤矿(数据区),而把缓冲器比如 为运煤车,想要得到煤一般都通过运煤车来获取,而不是直接和煤矿取煤。用户想得到数据需要经过几个步骤:

    一、用户与ByteBuffer的交互

        向ByteBuffer中输入数据,有两种方式但都必须先为ByteBuffer指定容量

             ByteBuffer buff = ByteBuffer.allocate(BSIZE);

         a)  buff  =  ByteBuffer.wrap("askjfasjkf".getBytes())注意:wrap方法是静态函数且只能接收byte类型的数据,任何其他类型的数据想通过这种方式传递,需要进行类型的转换。

         b)  buff.put();可以根据数据类型做相应调整,如buff.putChar(chars),buff.putDouble(double)等

    二、FileChannel 与 ByteBuffer的交互:

        缓冲器向通道输入数据

         FileChannel fc = new FileInputStream().getChannel();  

         fc.write(buff);

         fc.close();

    三、 用户与ByteBuffer交互

        通道向缓冲器送入数据

        FileChannel fc =  new FileOutputStream().getChannel();

        fc.read( buff);

        fc.flip();

    四、呈现给用户(三种方式)

      1)String encoding = System.getProperty("file.encoding");

       System.out.println("Decoded using " + encoding + ": "  + Charset.forName(encoding).decode(buff));   

      2)System.out.println(buff.asCharBuffer());//这种输出时,需要在输入时就进行编码getBytes("UTF-8")

      3) System.out.println(buff.asCharBuffer());//通过CharBuffer向ByteBuffer输入 buff.asCharBuffer().put

    fc.rewind();
  • 相关阅读:
    Atitit.Java exe bat  作为windows系统服务程序运行
    Atitit. Object-c语言 的新的特性  attilax总结
    Atitit. Object-c语言 的新的特性  attilax总结
    Atitit。Time base gc 垃圾 资源 收集的原理与设计
    Atitit。Time base gc 垃圾 资源 收集的原理与设计
    Atitit.go语言golang语言的新的特性  attilax总结
    Atitit.go语言golang语言的新的特性  attilax总结
    Atitit.pdf 预览 转换html attilax总结
    Atitit.pdf 预览 转换html attilax总结
    Atitit.office word  excel  ppt pdf 的web在线预览方案与html转换方案 attilax 总结
  • 原文地址:https://www.cnblogs.com/hanease/p/15717332.html
Copyright © 2011-2022 走看看