zoukankan      html  css  js  c++  java
  • NIO的初步入门

    NIO
    1. java NIO简介

          Java NIO 简介 是从java1.4版本开始引入的一个新的IO AP可以替代标准java  IO API

           NIO与原来的IO有同样的作用和目的,但是使用方式完全不同,NIO支持面向缓冲区的,基于通道的IO操作,NIO将以更加高效的方式进行文件的读与写操作。

            2Java NIO IO的主要区别

    IO

    NIO

    面向流

    面向缓冲区

    阻塞IO

    非阻塞

    选择器

    传统IO

     

    NIO 通道负责连接,缓冲区负责数据的传输。

     

      /**
         *  Buffer(缓冲区)用于存储数据 本质就是数组,存储不同数据类型的数据
         *  根据数据类型不同(boolean 除外),提供了相应类型的缓冲区。
         *  ByteBuffer
         *  CharBuffer
         *  ShortBuffer
         *  IntBuffer
         *  LongBuffer
         *  FloatBuffer
         *  DoubleBuffer
         *  上述缓冲区的管理方式几乎一致,通过allocate()获取缓冲区
         * 缓冲区中存取数据的两个核心方法
         * put() 存入数据到缓冲区中
         * get() 获取缓冲区中的数据
         * 缓存区中的四个核心属性
         *     private int mark = -1; 标记,表示记录当前position 的位置 可以通过reset()恢复到mark的位置
         *     private int position = 0;位置,缓存区中正在操作数据的位置
         *     private int limit;  界限,表示缓冲区中可以操作数据的大小 (limit后面的数据我们是不能就进行读写的)
         *     private int capacity; 容量:表示缓存区中组最大存储数据的容量,一旦声明不可改变
         *    0<=mark<= position<=limit<=capacity
         *
         * 直接缓冲区与非直接缓冲区
         * 非直接缓冲区:通过allocate()方法分配缓冲区,将缓冲区建立子字JVM的内存中
         *
         * 直接缓冲区:通过allocateDirect()方法分配直接缓冲区。将缓冲区建立在物理内存中,可以提高效率
         */
     @Test
        public void test01(){
            /*创建直接缓冲区*/
            ByteBuffer bytebuffer = ByteBuffer.allocate(1024);//给缓冲区设置一个大小
         //   ByteBuffer bytebufferD = ByteBuffer.allocateDirect(1024);//给缓冲区设置一个大小,直接缓冲区
    
            /*判断是不是直接缓冲区*/
            System.out.println(bytebuffer.isDirect());
    
            System.out.println("==================allocated");
    
           System.out.println(bytebuffer.position());
           System.out.println(bytebuffer.capacity());
           System.out.println(bytebuffer.limit());
    
            //利用put()存入数据到缓冲区中
            String str = "aynu";
            bytebuffer.put(str.getBytes());
    
           System.out.println("================put=================");
    
            System.out.println(bytebuffer.position());
            System.out.println(bytebuffer.capacity());
            System.out.println(bytebuffer.limit());
    
    
            System.out.println("===================flip==================");
            //切换到读取数据的模式
            bytebuffer.flip();
    
    
            System.out.println(bytebuffer.position());
            System.out.println(bytebuffer.capacity());
            System.out.println(bytebuffer.limit());
    
            //利用get()方法读取缓冲区中的数据
            System.out.println("===============get=====================");
             byte[] dst =  new byte[bytebuffer.limit()];
             bytebuffer.get(dst);
             System.out.println(new String(dst,0,dst.length));
    
            System.out.println(bytebuffer.position());
            System.out.println(bytebuffer.capacity());
            System.out.println(bytebuffer.limit());
    
            //rewind 可重复读数据
            System.out.println("==================rewind===================");
            bytebuffer.rewind();
            System.out.println(bytebuffer.position());
            System.out.println(bytebuffer.capacity());
            System.out.println(bytebuffer.limit());
    
    
            //clear()清空缓冲区 但是缓冲区的数据还在,但是处于被遗忘状态,就是核心属性都变成了最初状态
            System.out.println("================clear==================");
            bytebuffer.clear();
    
            System.out.println(bytebuffer.position());
            System.out.println(bytebuffer.capacity());
            System.out.println(bytebuffer.limit());
    
            //可以取出数据
            System.out.println((char) bytebuffer.get());
    
        }

    执行结果

    false
    ==================allocated
    0
    1024
    1024
    ================put=================
    4
    1024
    1024
    ===================flip==================
    0
    1024
    4
    ===============get=====================
    aynu
    4
    1024
    4
    ==================rewind===================
    0
    1024
    4
    ================clear==================
    0
    1024
    1024
    a
    
    Process finished with exit code 0
    执行结果
      @Test
        public void   test02(){
            String str  ="abced";
    
            //设置缓冲区大小
            ByteBuffer buffer = ByteBuffer.allocate(1024);
    
            //存放数据
            buffer.put(str.getBytes());
    
            //切换到读数据的模式
            buffer.flip();
    
            /*创建一个数组将读取的数据保存到这个里面*/
            byte[] bytes = new byte[buffer.limit()];
            buffer.get(bytes,0,2);
            //将读取到的数据组委字符串输出来
            System.out.println(new String (bytes,0,2));
    
            System.out.println("基本属性的大小");
            System.out.println("position1========"+buffer.position());
    
    
            /*通过mark 进行标记*/
            buffer.mark();
            buffer.get(bytes,2,2);
            System.out.println(new String(bytes,2,2));
            System.out.println("position2========"+buffer.position());
    
    
            //reset() 重置,恢复到mark的位置
            buffer.reset();
            System.out.println("position3========"+buffer.position());
    
    
            //判断缓冲区中是否还有剩余的数据
            if(buffer.hasRemaining()){
    
                //获取缓冲区中可以操作的数量
                System.out.println(buffer.remaining());
            }
        }
    ab
    基本属性的大小
    position1========2
    ce
    position2========4
    position3========2
    3
    
    Process finished with exit code 0
    执行结果

    ====================================================================

    import java.nio.Buffer;
    import java.nio.ByteBuffer;
    
    /**
     * Description: NIOproject-01
     * Created by lenovo on 2019/4/22 15:01
     */
    public class TestNio {
    
       public static void main (String[] args){
    
           String str ="zhulina";
           //创建缓冲区
           ByteBuffer buffer = ByteBuffer.allocate(1024);
    
           //将数据存放到缓存区中
           buffer.put(str.getBytes());
    
           //转换为读取模式
           buffer.flip(); //一定要写在前面否则会错哦
    
           //读取数据
           byte[] b= new byte[buffer.limit()];
    
    
           //读取缓冲区的数据
           buffer.get(b);
    
           //将数据打印在控制台,我并没有读取缓冲区的数据
           System.out.println(new String(b,0,b.length).toString());
    
    
       }
    }

    ===================================================================

     3.缓冲区(Buffer)和通道

              Java NIO系统的核心在于 通道(channel)和缓冲区(buffer。通道表示打开到IO设备(例如:文件,套接字)的而连接。若需要使用NIO系统,需要获取用于连接IO设备的通道以   及用于容纳数据的缓冲区,然后操作缓冲区,对数据进行处理。

      简言之,channel负责传输,buffer负责存储。

    缓冲区(buffer

    一个用于特定基本数据类型的容器,有java.nio包定义的,所有缓冲区都是buffer抽象类的子类。

    JavaNIO 中的Buffer主要用于与NIO通道进行交互,数据是从通道读入缓冲区,从缓冲区写入通道中的。

            4.文件通道

            5.NIO的非阻塞时式网络通信

    选择器

    SockerChannel ,ServerSockertChannel  ,DatagramChannel

              

             6.管道

             7.Java NIO2PathPathsFiles

     测试用例1:

    TestNioSocket

    import org.junit.Test;
    
    import java.io.File;
    import java.io.IOException;
    import java.net.InetSocketAddress;
    import java.nio.ByteBuffer;
    import java.nio.channels.FileChannel;
    import java.nio.channels.ServerSocketChannel;
    import java.nio.channels.SocketChannel;
    import java.nio.channels.WritableByteChannel;
    import java.nio.file.Paths;
    import java.nio.file.StandardOpenOption;
    import java.util.WeakHashMap;
    
    /**
     * Description: NIOproject-01
     * Created by lenovo on 2019/4/23 21:25
     */
    public class MyTest {
    
    
        @Test
        public void Client() throws IOException {
           /*建立网络通道*/
            SocketChannel socketChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1", 9988));
    
            /*建立文件通道*/
            FileChannel fileChannel = FileChannel.open(Paths.get("E:\sturts2\NIOproject-01\src\main\webapp\1.txt"), StandardOpenOption.READ);
    
            /*建立缓冲区*/
            ByteBuffer buffer = ByteBuffer.allocate(1024);
    
            /*将通道中的数据读入到缓冲区中*/
            while (fileChannel.read(buffer)!=-1){
                buffer.flip();
                socketChannel.write(buffer);
                buffer.clear();
    
            }
        //    socketChannel.shutdownOutput();
            /*写上一个客户端的响应*/
    
            int len =0;
    
           /* while ((len=buffer.limit())!=-1){
                buffer.flip();
                System.out.println("客户端"+ new String(buffer.array(),0,len));
    
                buffer.clear();
    
            }*/
            socketChannel.close();
            fileChannel.close();
    
        }
    
        @Test
        public void Server() throws IOException {
            ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
    
            FileChannel fileChannel = FileChannel.open(Paths.get("E:\sturts2\NIOproject-01\src\main\webapp\2.txt"),  StandardOpenOption.WRITE);
    
            /*绑定连接*/
            serverSocketChannel.bind(new InetSocketAddress(9988));
    
            /*建立缓冲区*/
            ByteBuffer buffer = ByteBuffer.allocate(1024);
    
            /*获取客户端的通道*/
            SocketChannel acceptChannel = serverSocketChannel.accept();
    
    
    
            while (acceptChannel.read(buffer)!=-1){
                buffer.flip();
                fileChannel.write(buffer);
                buffer.clear();
            }
            /*建立一个响应*/
    /*
            int len=0;
            while ((len= buffer.limit())!=-1){
    
                buffer.flip();
               System.out.println("客户端给出的响应"+new String(buffer.array(),0,len));
                buffer.clear();
    
            }*/
            serverSocketChannel.close();
            fileChannel.close();
            acceptChannel.close();
    
    
    
    
        }
    
    }
    TestNioSocket
    import com.sun.org.apache.bcel.internal.generic.Select;
    import org.junit.Test;
    
    import java.io.IOException;
    import java.net.InetSocketAddress;
    import java.nio.ByteBuffer;
    import java.nio.channels.*;
    import java.util.Date;
    import java.util.Iterator;
    import java.util.Scanner;
    
    /**
     *使用NIO完成网络通信的三个核心
     * 1.通道(Channel)负责连接
     *
     *java.nio.channels.Channel接口
     *    |--SelectableChannel
     *        |---SocketChannel
     *        |---ServerSocketChannel
     *        |---DatagramChannel
     *
     *        |---Pipe>SinkChannel
     *        |---PipeSourceChannel
     *
     *
     * 2.缓冲区(Buffer) 负责数据的存取
     *
     *
     * 3.选择器(Selector)是SelectableChannel的多路复用 。用于监控SelectableChannel的IO状况
     *
     *
     *
     */
    
    public class TestNonBlockingNio {
    //客户端
        @Test
        public void Client() throws IOException {
    
            //获取通道
            SocketChannel sChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1", 9898));
    
            //切换非阻塞模式
            sChannel.configureBlocking(false);
    
            //3.分配制定大小的缓冲区
            ByteBuffer buf = ByteBuffer.allocate(1024);
    
            //4.发送数据给服务端
            Scanner scan = new Scanner(System.in);
    
            while (scan.hasNext()){
                String str = scan.next();
                buf.put((new Date().toString()+"
    "+str).getBytes());
                buf.flip();
                sChannel.write(buf);
                buf.clear();
    
            }
    
    
    
            //5.关闭通道
            sChannel.close();
    
    
        }
    //服务端
        @Test
        public void Server() throws IOException {
             //1.获取通道
             ServerSocketChannel ssChannel = ServerSocketChannel.open();
    
             //2.切换非阻塞模
            ssChannel.configureBlocking(false);
    
            //3.绑定连接
            ssChannel.bind(new InetSocketAddress(9898));
    
            //4.获取选择器
            Selector selector = Selector.open();
    
            //5.将通道注册到选择器上面,并且指定 监听接受事件
            ssChannel.register(selector, SelectionKey.OP_ACCEPT);
    
            //6.轮询式的获取选择器上已经准备就绪的事件
            while (selector.select()>0){
                //获取当前选择器中所有注册的选择键(已就绪的监听事件)
                Iterator<SelectionKey> it = selector.selectedKeys().iterator();
    
                while (it.hasNext()){
                    //8.获取准备就绪的事件
                    SelectionKey sk = it.next();
    
                    //9.判断是什么事件准备就绪
                    if (sk.isAcceptable()){
                        //10若接收就绪获取客户端连接
    
                        SocketChannel sChannel = ssChannel.accept();
    
                      //11.切换非阻塞模式
                        sChannel.configureBlocking(false);
    
                        //12.将该通道注册到选择器上
                        sChannel.register(selector,SelectionKey.OP_READ);
    
                    }else if(sk.isReadable()){
                        //13.获取当前选择器上 ’读就绪‘ 状态的通道
    
                        SocketChannel sChannel = (SocketChannel) sk.channel();
    
                        //14.读取数据
                        ByteBuffer buf = ByteBuffer.allocate(1024);
    
                        int len=0;
    
                        while ((len =sChannel.read(buf))>0){
                              buf.flip();
                              System.out.println(new String(buf.array(),0,len));
                              buf.clear();
    
                        }
                    }
                    //15.取消选择键selectorkey
                    it.remove();
    
    
    
    
    
                }
    
    
            }
    
    
    
    
    
    
    
    
    
        }
    
    
    
    }
    TestNonBlockingNio
    import org.junit.Test;
    
    import java.io.IOException;
    import java.net.InetSocketAddress;
    import java.nio.ByteBuffer;
    import java.nio.channels.DatagramChannel;
    import java.nio.channels.SelectionKey;
    import java.nio.channels.Selector;
    import java.util.Date;
    import java.util.Iterator;
    import java.util.Scanner;
    
    /**
     * Description: NIOproject-01
     * Created by lenovo on 2019/4/23 11:09
     */
    public class TestNonBlokingNio2 {
        @Test
        public void send() throws IOException {
            DatagramChannel dc = DatagramChannel.open();
    
            dc.configureBlocking(false);
    
            ByteBuffer buf = ByteBuffer.allocate(1024);
    
            Scanner scanner = new Scanner(System.in);
    
            while (scanner.hasNext()){
                String str = scanner.next();
                buf.put((new Date().toString()+":
    "+str).getBytes());
                buf.flip();
                dc.send(buf,new InetSocketAddress("127.0.0.1",9898));
                buf.clear();
            }
            dc.close();
        }
    
        @Test
        public void review() throws IOException {
            DatagramChannel dc = DatagramChannel.open();
    
            dc.configureBlocking(false);
    
            dc.bind(new InetSocketAddress(9898));
    
            Selector selector = Selector.open();
    
            while (selector.select()>0){
                Iterator<SelectionKey> it = selector.selectedKeys().iterator();
    
                while (it.hasNext()){
    
                    SelectionKey sk = it.next();
    
                    if (sk.isReadable()){
                        ByteBuffer buf = ByteBuffer.allocate(1024);
    
                        dc.receive(buf);
                        buf.flip();
    
                        System.out.println(new String(buf.array(),0,buf.limit()));
                        buf.clear();
    
    
    
    
    
                    }
                }
    
    it.remove();
    
    
    
    
            }
    
    
        }
    }
    TestNonBlokingNio2
    import org.junit.Test;
    
    import java.io.IOException;
    import java.net.InetSocketAddress;
    import java.nio.ByteBuffer;
    import java.nio.channels.FileChannel;
    import java.nio.channels.ServerSocketChannel;
    import java.nio.channels.SocketChannel;
    import java.nio.file.Paths;
    import java.nio.file.StandardOpenOption;
    
    /**
     * Description: NIOproject-01
     * Created by lenovo on 2019/4/22 21:58
     */
    public class TestBlockNio2 {
    
    //客户端
        @Test
        public void Client() throws IOException {
            SocketChannel sChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1", 9898));
    
            FileChannel inChannel = FileChannel.open(Paths.get("1.png"), StandardOpenOption.READ);
    
            ByteBuffer buf = ByteBuffer.allocate(1024);
    
            while (inChannel.read(buf)!=-1){
                buf.flip();
                sChannel.write(buf);
                buf.clear();
            }
            sChannel.shutdownOutput();
    
    
            //接收服务端的反馈
             int len =0;
            while ((len= sChannel.read(buf)) !=-1){
                buf.flip();
                System.out.println(new String(buf.array(),0,len));
                buf.clear();
            }
            inChannel.close();
            sChannel.close();
    
    
    
        }
    
    //服务端
        @Test
        public void Server() throws IOException {
    
            ServerSocketChannel ssChannel = ServerSocketChannel.open();
    
            FileChannel outChannel = FileChannel.open(Paths.get("1.png"), StandardOpenOption.WRITE, StandardOpenOption.CREATE);
            ssChannel.bind(new InetSocketAddress(9988));
            SocketChannel sChannel = ssChannel.accept();
    
            ByteBuffer buf = ByteBuffer.allocate(1024);
            while (sChannel.read(buf)!=-1){
                buf.flip();
                outChannel.write(buf);
                buf.clear();
            }
            //发送反馈给客户端
    
            buf.put("服务端接收数据成功".getBytes());
            buf.flip();
            sChannel.write(buf);
    
            sChannel.close();
            ssChannel.close();
            outChannel.close();
    
    
    
    
    
    
    
        }
    }
    TestBlockNio2
    import org.junit.Test;
    
    import java.io.*;
    import java.nio.ByteBuffer;
    import java.nio.CharBuffer;
    import java.nio.MappedByteBuffer;
    import java.nio.channels.FileChannel;
    import java.nio.charset.CharacterCodingException;
    import java.nio.charset.Charset;
    import java.nio.charset.CharsetDecoder;
    import java.nio.charset.CharsetEncoder;
    import java.nio.file.Path;
    import java.nio.file.Paths;
    import java.nio.file.StandardOpenOption;
    import java.security.PublicKey;
    import java.util.Map;
    import java.util.Set;
    import java.util.SortedMap;
    
    /**
     * Channel 用于源节点与目标节点的连接,在java NIO 中负责缓冲区数据的传输,Channel本身不存储数据,因此需要配合
     * 缓冲区进行传输
     * 二.通道的主要实现类
     *     fillChannel
     *     socketChannel
     *     serverSocketChannel
     *     DatagramChannel
     *
     *  三.获取通道
     *   1.java 针对支持通道的类提供了 getChannel()方法
     *   本地IO
     *   FileInputStream/FileOutPutStream
     *   RandomAccessFile
     *
     *   网络 IO
     *   Socket
     *   ServerSocker
     *   DatagramSocket
     *   2.在jdk 1.7中的NIO.2 针对各个通道提供了静态方法 open()
     *   在jdk 1.7 中的NIO.2 的files  工具类的newByteChannel()
     * 四 通道之间的数据传输
     * transferForm()
     * transferTo()
     *
     * 五分散(scatter)与聚集(Gather)
     * 分散读取(scattering reads):将通道中的数据分散到多个缓冲区中
     * 聚集写入(Gathering Writes):将多个缓冲区中的数据聚集到同道中
     *
     *六字符集
     * 编码 字符串---》字节数组
     * 解码 字节数组---》字符串
     */
    public class TestChannel {
    
        @Test
        public void Test01()  {
    
            //1.利用通道完成文件的复制(非直接缓冲区)
    
            FileInputStream fileInputStream = null;
            FileOutputStream fileOutputStream = null;
            FileChannel inputchannel = null;
            FileChannel outChannel = null;
            try {
                fileInputStream = new FileInputStream("E:\sturts2\NIOproject-01\src\main\webapp\1.png");
                fileOutputStream = new FileOutputStream("E:\sturts2\NIOproject-01\src\main\webapp\2.png");
    
                //获取通道
                inputchannel = fileInputStream.getChannel();
                outChannel = fileOutputStream.getChannel();
    
                //分配指定大小缓冲区
                ByteBuffer buffer = ByteBuffer.allocate(1024);
    
    
                //将通道中的数据存放入缓冲区中
                while (inputchannel.read(buffer)!=-1){
                    //切换到读取数据的模式
                    buffer.flip();
    
                    //将缓存区中的数据写入到通道中
                    outChannel.write(buffer);
    
                    buffer.clear();//清空缓存区
    
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (inputchannel!=null) {
    
                    try {
                        inputchannel.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                    if (outChannel!=null){
    
                        try {
                            outChannel.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                    if (fileInputStream!=null){
    
                        try {
                            fileInputStream.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                    if (fileOutputStream!=null){
    
                        try {
                            fileOutputStream.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
    
            }
    
        }
        @Test
        public void Test02(){
        //使用直接缓冲区完成文件的复制(内存映射文件)
            long start = System.currentTimeMillis();
    
    
            FileChannel inChannel = null;
            FileChannel outChannel = null;
            try {
                inChannel = FileChannel.open(Paths.get("E:\sturts2\NIOproject-01\src\main\webapp\1.png"), StandardOpenOption.READ);
                outChannel = FileChannel.open(Paths.get("E:\sturts2\NIOproject-01\src\main\webapp\3.png"), StandardOpenOption.WRITE, StandardOpenOption.READ,StandardOpenOption.CREATE);
    
                //内存映射文件
                MappedByteBuffer inmapBuffer = inChannel.map(FileChannel.MapMode.READ_ONLY, 0, inChannel.size());
                MappedByteBuffer outmapBuffer = outChannel.map(FileChannel.MapMode.READ_WRITE, 0, inChannel.size());
    
                //直接对缓冲区进行数据的读写操作
                byte[] dst = new byte[inmapBuffer.limit()];
                inmapBuffer.get(dst);
                outmapBuffer.put(dst);
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (inChannel!=null){
    
                    try {
                        inChannel.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (outChannel!=null){
    
                    try {
                        outChannel.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
    
                }
            }
         long end =   System.currentTimeMillis();
            System.out.println("耗费时间为"+(end-start));
    
        }
    
        //通道之间的数据传输(直接缓冲区)
        @Test
        public void test03() throws IOException {
    
        FileChannel inChannel = FileChannel.open(Paths.get(""), StandardOpenOption.READ);
        FileChannel outChannel = FileChannel.open(Paths.get(""), StandardOpenOption.READ, StandardOpenOption.WRITE, StandardOpenOption.CREATE);
    
      //  inChannel.transferTo(0,inChannel.size(),outChannel);
        outChannel.transferFrom(inChannel,0,inChannel.size());
    
        inChannel.close();
        outChannel.close();
    }
    /*分散和聚集*/
       @Test
       public void test04() throws IOException {
    
           RandomAccessFile raf1 = new RandomAccessFile("1.txt", "rw");
    
           //获取通道
           FileChannel channel = raf1.getChannel();
    
           //分配指定大小的缓冲区
           ByteBuffer buf1 = ByteBuffer.allocate(100);
           ByteBuffer buf2 = ByteBuffer.allocate(1024);
    
           //3.分散读取
           ByteBuffer[] bufs = {buf1,buf2};
           long read = channel.read(bufs);
    
           for(ByteBuffer byteBuffer: bufs){
               byteBuffer.flip();//切换到读操作
           }
           System.out.println(new String(bufs[0].array(),0,bufs[0].limit()));
           System.out.println("=================================");
           System.out.println(new String(bufs[1].array(),0,bufs[1].limit()));
    
           //4.聚集写入
           RandomAccessFile raf2 = new RandomAccessFile("2.txt", "rw");
           FileChannel channel1 = raf2.getChannel();
           channel1.write(bufs);
    
    
       }
    
          @Test
          public void test05(){
           //字符集
              Map<String, Charset> map = Charset.availableCharsets();
    
              Set<Map.Entry<String, Charset>> entries = map.entrySet();
    
              for (Map.Entry<String,Charset> entry: entries
                   ) {
                  System.out.println(entry.getKey()+"="+entry.getValue());
              }
              
              
    
          }
          @Test
          public void  Test06() throws CharacterCodingException {
              Charset charset = Charset.forName("GBK");
    
              //获取编码器
              CharsetEncoder encoder = charset.newEncoder();
    
              //获取解码器
              CharsetDecoder decoder1 = charset.newDecoder();
    
              //指定缓冲区大小
              CharBuffer buffer = CharBuffer.allocate(1024);
               buffer.put("中国");
               buffer.flip();
    
               //编码
              ByteBuffer encode = encoder.encode(buffer);
    
              for(int i=0;i<4;i++){
                  System.out.println(encode.get());
    
              }
    
             //解码
              encode.flip();
              CharBuffer decode2 = decoder1.decode(encode);
              System.out.println(decode2.toString());
    
              System.out.println("=================================");
    
            //  Charset charset1 = Charset.forName("UTF-8");
              Charset charset1 = Charset.forName("GBK");
              encode.flip();
              CharBuffer decode3 = charset1.decode(encode);
              System.out.println(decode3.toString());
    
    
          }
    
    
    
    
    
    
    }
    TestChannel
    import org.junit.Test;
    
    import java.nio.ByteBuffer;
    
    /**
     * Description: NIOproject-01
     * Created by lenovo on 2019/4/22 15:07
     */
    public class TestNio {
        /**
         *  Buffer(缓冲区)用于存储数据 本质就是数组,存储不同数据类型的数据
         *  根据数据类型不同(boolean 除外),提供了相应类型的缓冲区。
         *  ByteBuffer
         *  CharBuffer
         *  ShortBuffer
         *  IntBuffer
         *  LongBuffer
         *  FloatBuffer
         *  DoubleBuffer
         *  上述缓冲区的管理方式几乎一致,通过allocate()获取缓冲区
         * 缓冲区中存取数据的两个核心方法
         * put() 存入数据到缓冲区中
         * get() 获取缓冲区中的数据
         * 缓存区中的四个核心属性
         *     private int mark = -1; 标记,表示记录当前position 的位置 可以通过reset()恢复到mark的位置
         *     private int position = 0;位置,缓存区中正在操作数据的位置
         *     private int limit;  界限,表示缓冲区中可以操作数据的大小 (limit后面的数据我们是不能就进行读写的)
         *     private int capacity; 容量:表示缓存区中组最大存储数据的容量,一旦声明不可改变
         *    0<=mark<= position<=limit<=capacity
         *
         * 直接缓冲区与非直接缓冲区
         * 非直接缓冲区:通过allocate()方法分配缓冲区,将缓冲区建立子字JVM的内存中
         *
         * 直接缓冲区:通过allocateDirect()方法分配直接缓冲区。将缓冲区建立在物理内存中,可以提高效率
         */
    
    
        @Test
        public void test01(){
            /*创建直接缓冲区*/
            ByteBuffer bytebuffer = ByteBuffer.allocate(1024);//给缓冲区设置一个大小
         //   ByteBuffer bytebufferD = ByteBuffer.allocateDirect(1024);//给缓冲区设置一个大小,直接缓冲区
    
            /*判断是不是直接缓冲区*/
            System.out.println(bytebuffer.isDirect());
    
            System.out.println("==================allocated");
    
           System.out.println(bytebuffer.position());
           System.out.println(bytebuffer.capacity());
           System.out.println(bytebuffer.limit());
    
            //利用put()存入数据到缓冲区中
            String str = "aynu";
            bytebuffer.put(str.getBytes());
    
           System.out.println("================put=================");
    
            System.out.println(bytebuffer.position());
            System.out.println(bytebuffer.capacity());
            System.out.println(bytebuffer.limit());
    
    
            System.out.println("===================flip==================");
            //切换到读取数据的模式
            bytebuffer.flip();
    
    
            System.out.println(bytebuffer.position());
            System.out.println(bytebuffer.capacity());
            System.out.println(bytebuffer.limit());
    
            //利用get()方法读取缓冲区中的数据
            System.out.println("===============get=====================");
             byte[] dst =  new byte[bytebuffer.limit()];
             bytebuffer.get(dst);
             System.out.println(new String(dst,0,dst.length));
    
            System.out.println(bytebuffer.position());
            System.out.println(bytebuffer.capacity());
            System.out.println(bytebuffer.limit());
    
            //rewind 可重复读数据
            System.out.println("==================rewind===================");
            bytebuffer.rewind();
            System.out.println(bytebuffer.position());
            System.out.println(bytebuffer.capacity());
            System.out.println(bytebuffer.limit());
    
    
            //clear()清空缓冲区 但是缓冲区的数据还在,但是处于被遗忘状态,就是核心属性都变成了最初状态
            System.out.println("================clear==================");
            bytebuffer.clear();
    
            System.out.println(bytebuffer.position());
            System.out.println(bytebuffer.capacity());
            System.out.println(bytebuffer.limit());
    
            //可以取出数据
            System.out.println((char) bytebuffer.get());
    
        }
        @Test
        public void   test02(){
            String str  ="abced";
    
            //设置缓冲区大小
            ByteBuffer buffer = ByteBuffer.allocate(1024);
    
            //存放数据
            buffer.put(str.getBytes());
    
            //切换到读数据的模式
            buffer.flip();
    
            /*创建一个数组将读取的数据保存到这个里面*/
            byte[] bytes = new byte[buffer.limit()];
            buffer.get(bytes,0,2);
            //将读取到的数据组委字符串输出来
            System.out.println(new String (bytes,0,2));
    
            System.out.println("基本属性的大小");
            System.out.println("position1========"+buffer.position());
    
    
            /*通过mark 进行标记*/
            buffer.mark();
            buffer.get(bytes,2,2);
            System.out.println(new String(bytes,2,2));
            System.out.println("position2========"+buffer.position());
    
    
            //reset() 重置,恢复到mark的位置
            buffer.reset();
            System.out.println("position3========"+buffer.position());
    
    
            //判断缓冲区中是否还有剩余的数据
            if(buffer.hasRemaining()){
    
                //获取缓冲区中可以操作的数量
                System.out.println(buffer.remaining());
            }
        }
    
    }
    TestNio

     

     

  • 相关阅读:
    【2020NOI.AC省选模拟#5】C. 光滑序列
    【2020NOI.AC省选模拟#2】A. 旋转
    【2020NOI.AC省选模拟#1】B. Trie
    Redis 配置
    Redis 删除策略
    Redis 事务
    Redis 持久化
    Redis 通用指令
    Redis 数据类型实战案例
    Redis sorted_set
  • 原文地址:https://www.cnblogs.com/zhulina-917/p/10750301.html
Copyright © 2011-2022 走看看