Java|Java NIO(一)-Channel和Buffer

  1. Channel
    Channel类似于流,但和流不同,流是单向的只能读或写,Channel是既可以读又可以写。Channel常见的实现类有FileChannel、DatagramChannel、SocketChannel、ServerSocketChannel。BIO中的FileInputStream、FileOutputStream和RandomAccessFile能通过getChannel方法得到FileChannel对象
  2. Buffer
    Buffer是唯一能与Channel交互的对象,它的常见实现有ByteBuffer、ShortBuffer、IntBuffer、LongBuffer、DoubleBuffer、FloatBuffer、CharBuffer。Buffer有四个属性position、limit、capacity和mark,Buffer初始化的时候需要指定容量capacity,Buffer它的底层实现是一个数组,如下图,以ByteBuffer为例,position表示数组中下一个要读或写的位置,当向Buffer写完后(不一定写满),调用flip()方法,将Buffer的读写模式翻转,limit赋值为position,position赋值为0。mark是标记位置,可以通过reset()方法,将position值变为mark值。
public abstract class ByteBuffer extends Buffer implements Comparable { final byte[] hb; // Non-null only for heap buffers final int offset; boolean isReadOnly; // Valid only for heap buffers }

直接看看ByteBuffer的简单使用:
public class ByteBufferTest { public static void main(String[] args) { try { FileInputStream is = new FileInputStream("/home/reda/Documents/test/1.txt"); FileOutputStream fos = new FileOutputStream("/home/reda/Documents/test/1.txt"); FileOutputStream os = new FileOutputStream("/home/reda/Documents/test/2.txt"); FileChannel inChannel = is.getChannel(); FileChannel fosChannel = fos.getChannel(); FileChannel outChannel = os.getChannel(); //特殊情况,直接在channel传输 //inChannel.transferTo(0,inChannel.size(),outChannel); //outChannel.transferFrom(inChannel,0,inChannel.size()); ByteBuffer buffer = ByteBuffer.allocate(16); //写入内容 fosChannel.write(ByteBuffer.wrap("1234QAQ".getBytes("UTF-8"))); //while(inChannel.read(buffer) != -1) { //buffer.flip(); //outChannel.write(buffer); ////必须clear不然除了第一次,后面将读不进内容到Buffer //buffer.clear(); //}buffer.clear(); fosChannel.close(); inChannel.read(buffer); buffer.flip(); //将positon的位置标记在起始位置,将ByteBuffer中每个字节转为字符 buffer.mark(); while (buffer.hasRemaining()) { System.out.print((char)buffer.get()); } System.out.println(); //将positon的位置重置 buffer.reset(); CharBuffer charBuffer = buffer.asCharBuffer(); //打印乱码,ByteBuffer直接转成CharBuffer不行 System.out.println(charBuffer.toString()); //将ByteBuffer解码成utf8后,则能重新正确打印 CharBuffer charBuffer2 = Charset.forName("UTF-8").decode(buffer); System.out.println(charBuffer2.toString()); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }

【Java|Java NIO(一)-Channel和Buffer】ByteBuffer类有方法能转换成其他类型的Buffer

Java|Java NIO(一)-Channel和Buffer
文章图片
Buffer类型转换
public class BufferTest { public static void main(String[] args) { ByteBuffer buffer = ByteBuffer.wrap(new byte[]{0,0,0,0,0,0,0,'a'}); //byteBUffer result:0 0 0 0 0 0 0 97 while (buffer.hasRemaining()) System.out.print(buffer.get() + " "); //CharBuffer result:a CharBuffer charBuffer = ((ByteBuffer)buffer.rewind()).asCharBuffer(); while (charBuffer.hasRemaining()) System.out.print(charBuffer.get() + " "); //FloatBuffer result: 0.0 1.36E-43 FloatBuffer floatBuffer = ((ByteBuffer)buffer.rewind()).asFloatBuffer(); while (floatBuffer.hasRemaining()) System.out.print(floatBuffer.get() + " "); //IntBuffer result:0 97 IntBuffer intBuffer = ((ByteBuffer)buffer.rewind()).asIntBuffer(); while (intBuffer.hasRemaining()) System.out.print(intBuffer.get() + " "); //ShortBuffer result:0 0 0 97 ShortBuffer shortBuffer = ((ByteBuffer)buffer.rewind()).asShortBuffer(); while (shortBuffer.hasRemaining()) System.out.print(shortBuffer.get() + " "); //LongBuffer result:97 LongBuffer longBuffer = ((ByteBuffer)buffer.rewind()).asLongBuffer(); while (longBuffer.hasRemaining()) System.out.print(longBuffer.get() + " "); //DoubleBuffer result:4.8E-322 DoubleBuffer doubleBuffer = ((ByteBuffer)buffer.rewind()).asDoubleBuffer(); while (doubleBuffer.hasRemaining()) System.out.print(doubleBuffer.get() + " "); } }

  • 一字节:byte boolean
  • 二字节: char short
  • 四字节:int float
  • 八字节:long double
    ByteBuffer包装了一个8字节的数组,byteBuffer每个值有一个字节所以有8个值,同理char、short4个值(char的前三个值为空,没显示),int、float2个值,long和double一个值。

    推荐阅读