一.首先掌握NIO的三件套
缓冲区( Buffer)、选择器( Selector)、通道( Channel)
1.Buffer缓冲区
缓冲区实际上是一个容器对象,更直接的说,其实就是一个数组,在NIO库中,所有数据都是用媛冲区处理的。在读
取数据时,它是直接读到缓冲区中的在写入数据时,它也是写入到缓冲区中的;任何时候访问NO中的数据,都
是将它放到冲区中。而在面向流I/O系统中,所有数据都是直接写入或者直接将数据读取到 Stream对象中。
在NIO中,所有的缓冲区类型都继承于抽象类 Buffer,最常用的就是 Bytebuffer,对于Java中的基本类型,基本都有
一个具体 Buffer类型与之相对应
package com.tcc.test.io.buffer; /** * Copyright (C) @2021 * * @author: tcc * @version: 1.0 * @date: 2021/11/27 * @time: 21:53 * @description: */ import org.junit.Test; import java.nio.ByteBuffer; /** * 一、缓冲区(Buffer):在Java NIO中负责数据的存取。缓冲区就是数组。用于存储不同数据类型的数据。 * 根据数据类型不同(boolean 除外),提供了相应类型的缓冲区: * ByteBuffer * CharBuffer * ShortBuffer * IntBuffer * LongBuffer * FloatBuffer * DoubleBuffer * 上述缓冲区的管理方式几乎一致,通过allocate()获取缓冲区 * * 二、缓冲区存取数据的两个核心方法: * put():存入数据到缓冲区中 * get():获取缓冲区中的数据 * * 三、缓冲区中的四个核心属性: * capacity:容量,表示缓冲区中最大存储数据的容量。一旦声明不能改变。 * limit:界限,表示缓冲区中可以操作数据的大小。(limit 后数据不能进行读写) * position:位置,表示缓冲区中正在操作数据的位置。 * * mark:标记,表示记录当前position的位置。可以通过reset()恢复到mark的位置 * * 0<=mark<=position<=limit<=capacity * * 四、直接缓冲区和非直接缓冲区: * 非直接缓冲区:通过allocate()方法分配缓冲区,将缓冲区建立在JVM的内存中 * 直接缓冲区:通过allocateDirect()方法分配直接缓冲区,将缓冲区建立在物理内存中,可以提高效率。 * * @author ye.jinhui * @create 2017-02-18 10:30 */ public class TestBuffer { @Test public void test3() { //分配直接缓冲区 ByteBuffer buf = ByteBuffer.allocateDirect(1024); System.out.println(buf.isDirect());//用于判断此字节缓冲区是否为直接缓冲区 } @Test public void test2() { String str = "abcde"; ByteBuffer buf = ByteBuffer.allocate(1024);//非直接缓冲区:通过allocate()方法分配缓冲区,将缓冲区建立在JVM的内存中 buf.put(str.getBytes()); buf.flip();//写完数据,需要开始读的时候,将postion复位到0,并将limit设为当前postion。 byte[] dst = new byte[buf.limit()];//limit:界限,表示缓冲区中可以操作数据的大小。(limit 后数据不能进行读写) buf.get(dst,0,2); System.out.println("new String(dst,0,2)==="+new String(dst,0,2));//ab System.out.println("buf.position()=="+buf.position());//position:位置,表示缓冲区中正在操作数据的位置。 //mark():标记 buf.mark(); buf.get(dst,2,2); System.out.println("new String(dst,2,2)=="+new String(dst,2,2)); System.out.println("buf.position()=="+buf.position()); //reset():恢复到mark的位置 buf.reset(); System.out.println("buf.position()=="+buf.position()); //判断缓冲区中是否还有数据 if(buf.hasRemaining()) { //获取缓冲区中可以操作的数量 System.out.println("buf.remaining()=="+buf.remaining()); } } @Test public void test1() { String str = "abcde"; //1.分配一个指定大小的缓冲区 ByteBuffer buf = ByteBuffer.allocate(10); System.out.println("---------------alllocate()----------------"); System.out.println("buf.position()=="+buf.position());//0 System.out.println("buf.limit()=="+buf.limit());//10 System.out.println("buf.capacity()=="+buf.capacity());//10 //2.利用put()存入数据到缓冲区 buf.put(str.getBytes()); System.out.println("---------------put()----------------"); System.out.println("buf.position()=="+buf.position());//5 System.out.println("buf.limit()=="+buf.limit());//10 System.out.println("buf.capacity()=="+buf.capacity());//10 //3.切换到读取数据的模式 buf.flip(); System.out.println("---------------flip()----------------"); System.out.println("buf.position()=="+buf.position());//0 System.out.println("buf.limit()=="+buf.limit());//5 System.out.println("buf.capacity()=="+buf.capacity());//1o //4.利用get()读取缓冲区中的数据 byte[] dst = new byte[buf.limit()]; buf.get(dst); System.out.println("new String(dst,0,dst.length)=="+new String(dst,0,dst.length));//abcde System.out.println("---------------get()----------------"); System.out.println("buf.position()=="+buf.position());//5 System.out.println("buf.limit()=="+buf.limit());//5 System.out.println("buf.capacity()=="+buf.capacity());//10 //5.rewind():可重复读 buf.rewind(); System.out.println("---------------rewind()----------------"); System.out.println("buf.position()=="+buf.position());//0 System.out.println("buf.limit()=="+buf.limit());//5 System.out.println("buf.capacity()=="+buf.capacity());//10 //6.clear():清空缓冲区。但是缓冲区中的数据依然存在,但是处于"被遗忘"状态 buf.clear(); System.out.println("---------------clear()----------------"); System.out.println("buf.position()=="+buf.position());//0 System.out.println("buf.limit()=="+buf.limit());//10 System.out.println("buf.capacity()=="+buf.capacity());//10 System.out.println("(char) buf.get()=="+(char) buf.get());//a } }