zoukankan      html  css  js  c++  java
  • 2、nio的例子实践

    下面的例子,说明了,nio中的三大核心类的基本使用。buffer,channel,selector

      1 package com.shengsiyuan.nio;
      2 
      3 import org.junit.Test;
      4 
      5 import java.io.*;
      6 import java.net.*;
      7 import java.nio.ByteBuffer;
      8 import java.nio.IntBuffer;
      9 import java.nio.MappedByteBuffer;
     10 import java.nio.channels.*;
     11 import java.nio.channels.spi.SelectorProvider;
     12 import java.security.SecureRandom;
     13 import java.util.Arrays;
     14 import java.util.Iterator;
     15 import java.util.Set;
     16 
     17 public class NioTest1 {
     18 
     19     public static void main(String[] args) {
     20         IntBuffer intBuffer = IntBuffer.allocate(10);
     21 
     22         for (int i = 0; i < intBuffer.capacity(); i++) {
     23             int randomNumber = new SecureRandom().nextInt(20);
     24             intBuffer.put(randomNumber);
     25         }
     26 
     27         intBuffer.flip();//翻转,从写转到读状态
     28 
     29         while (intBuffer.hasRemaining()) {
     30             System.out.println(intBuffer.get());
     31         }
     32 
     33     }
     34 
     35     public void testBuffer() {
     36         IntBuffer intBuffer = IntBuffer.allocate(10);
     37 
     38         for (int i = 0; i < intBuffer.capacity(); i++) {
     39             int randomNumber = new SecureRandom().nextInt(20);
     40             intBuffer.put(randomNumber);
     41         }
     42 
     43         intBuffer.flip();//翻转,从写转到读状态
     44 
     45         while (intBuffer.hasRemaining()) {
     46             System.out.println(intBuffer.get());
     47         }
     48     }
     49 
     50     /**
     51       * @ClassName:      NioTest1
     52       * @Description:     描述  读文件
     53       * @Author:         
     54       * @CreateDate:     2019/8/27 21:26
     55       * @Version:        1.0
     56      */
     57     @Test
     58     public void testChannelRead() {
     59         try {
     60             FileInputStream fileInputStream = new FileInputStream("NioTest1.txt");
     61 
     62             FileChannel fileChannel = fileInputStream.getChannel();
     63 
     64             ByteBuffer byteBuffer = ByteBuffer.allocate(512);
     65 
     66             fileChannel.read(byteBuffer);
     67 
     68             byteBuffer.flip();
     69 
     70             while(byteBuffer.remaining() > 0) {
     71 
     72                 byte b = byteBuffer.get();
     73                 System.out.println("char is : " + (char) b);
     74 
     75                 if((char)b == 'e') {
     76                     byteBuffer.mark();
     77                 }
     78             }
     79 
     80             System.out.println(byteBuffer.position());
     81             System.out.println(byteBuffer.limit());
     82             System.out.println(byteBuffer.capacity());
     83 
     84             byteBuffer.reset();
     85 
     86 //            System.out.println(byteBuffer.mark());
     87             System.out.println(byteBuffer.position());
     88             System.out.println(byteBuffer.limit());
     89             System.out.println(byteBuffer.capacity());
     90 
     91 
     92             fileChannel.close();
     93             fileInputStream.close();
     94 
     95         } catch (Exception e) {
     96             e.printStackTrace();
     97         }
     98     }
     99 
    100     /**
    101       * @ClassName:      NioTest1
    102       * @Description:     描述  写文件
    103       * @Author:         
    104       * @CreateDate:     2019/8/27 21:25
    105       * @Version:        1.0
    106      */
    107     @Test
    108     public void testChannelWrite() {
    109         try{
    110             FileInputStream fileInputStream = new FileInputStream("NioTest1.txt");
    111             FileChannel fileChannel = fileInputStream.getChannel();
    112 
    113             FileChannel randowFileChannel = new RandomAccessFile(new File("NioTest1.txt"),"rw").getChannel();
    114 
    115             ByteBuffer byteBuffer = ByteBuffer.allocate(512);
    116 
    117             byte[] byteArr = "hello nio  nihao!".getBytes();
    118 
    119             byteBuffer.put(byteArr);
    120 
    121 
    122             byteBuffer.flip();
    123 
    124 //            fileChannel.write(byteBuffer);
    125 
    126             randowFileChannel.write(byteBuffer);
    127         }catch (Exception e) {
    128             e.printStackTrace();
    129         }
    130     }
    131 
    132     /**
    133       * @ClassName:      NioTest1
    134       * @Description:     描述  读写文件
    135       * @Author:         
    136       * @CreateDate:     2019/8/27 21:25
    137       * @Version:        1.0
    138      */
    139     @Test
    140     public void testChannelReadAndWrite() {
    141         try {
    142             FileInputStream fileInputStream = new FileInputStream("input.txt");
    143             FileOutputStream fileOutputStream = new FileOutputStream("out.txt");
    144 
    145             FileChannel inputFileChannel = fileInputStream.getChannel();
    146             FileChannel outputFileChannel = fileOutputStream.getChannel();
    147 
    148             ByteBuffer byteBuffer = ByteBuffer.allocate(512);
    149 
    150             while(inputFileChannel.read(byteBuffer) != -1) {
    151 
    152                 byteBuffer.flip();
    153 
    154                 outputFileChannel.write(byteBuffer);
    155 
    156 //                byteBuffer.clear();
    157             }
    158 
    159         }catch (Exception e) {
    160             e.printStackTrace();
    161         }
    162 
    163     }
    164 
    165     /**   
    166       * @ClassName:      NioTest1
    167       * @Description:     描述  切下部分的byteBuffer 作为一个快照,可以实现同步
    168       * @Author:         
    169       * @CreateDate:     2019/8/27 21:24
    170       * @Version:        1.0
    171      */
    172     @Test
    173     public void testSlice() {
    174         try{
    175             ByteBuffer byteBuffer = ByteBuffer.allocate(512);
    176 
    177             for (int i = 0; i < 20; i++) {
    178                 byteBuffer.put((byte)i);
    179             }
    180 //            byteBuffer.flip();
    181 
    182             ByteBuffer newByteBuffer = byteBuffer.slice();
    183 
    184             byteBuffer.put((byte)'a');
    185             byteBuffer.put((byte)'b');
    186 
    187 //            newByteBuffer.flip();
    188             System.out.println(newByteBuffer.get(0));
    189 
    190 //            byteBuffer.put(0, (byte)9);
    191 
    192             newByteBuffer.put(0, (byte)9);
    193 
    194             System.out.println(byteBuffer.get(20));
    195 
    196             System.out.println(newByteBuffer.get(0));
    197 
    198 
    199         }catch (Exception e) {
    200             e.printStackTrace();
    201         }
    202     }
    203 
    204     /**   
    205       * @ClassName:      NioTest1
    206       * @Description:     描述  只读的byteBuffer
    207       * @Author:         
    208       * @CreateDate:     2019/8/27 21:24
    209       * @Version:        1.0
    210      */
    211     @Test
    212     public void testReadonlyBuffer() {
    213 
    214         ByteBuffer byteBuffer = ByteBuffer.allocate(512);
    215         for (int i = 0; i < 10; i++) {
    216             byteBuffer.put((byte)i);
    217         }
    218 
    219         ByteBuffer readOnlyBuffer = byteBuffer.asReadOnlyBuffer();
    220 
    221         readOnlyBuffer.position(0);
    222 
    223         readOnlyBuffer.put((byte)1);
    224 
    225     }
    226 
    227     /**   
    228       * @ClassName:      NioTest1
    229       * @Description:     描述  通过直接内存,零拷贝来处理文件
    230       * @Author:         
    231       * @CreateDate:     2019/8/27 21:23
    232       * @Version:        1.0
    233      */
    234     @Test
    235     public void testChannelReadAndWriteDirect() {
    236         try {
    237             FileInputStream fileInputStream = new FileInputStream("input.txt");
    238             FileOutputStream fileOutputStream = new FileOutputStream("out.txt");
    239 
    240             FileChannel inputFileChannel = fileInputStream.getChannel();
    241             FileChannel outputFileChannel = fileOutputStream.getChannel();
    242 
    243             ByteBuffer byteBuffer = ByteBuffer.allocateDirect(512);
    244 
    245             while(inputFileChannel.read(byteBuffer) != -1) {
    246 
    247                 byteBuffer.flip();
    248 
    249                 outputFileChannel.write(byteBuffer);
    250 
    251                 byteBuffer.clear();
    252             }
    253 
    254         }catch (Exception e) {
    255             e.printStackTrace();
    256         }
    257 
    258     }
    259 
    260     /**   
    261       * @ClassName:      NioTest1  内存映射,来修改文件  而不操作buffer
    262       * @Description:     描述 
    263       * @Author:         
    264       * @CreateDate:     2019/8/27 21:23
    265       * @Version:        1.0
    266      */
    267     @Test
    268     public void testMapBuffer() throws Exception {
    269         RandomAccessFile randomAccessFile = new RandomAccessFile("NioTest1.txt", "rw");
    270         FileChannel fileChannel = randomAccessFile.getChannel();
    271 
    272         MappedByteBuffer mappedByteBuffer = fileChannel.map(FileChannel.MapMode.READ_WRITE, 0, 5);
    273 
    274         mappedByteBuffer.put(0, (byte)'a');
    275         mappedByteBuffer.put(3, (byte)'b');
    276 
    277         fileChannel.close();
    278         randomAccessFile.close();
    279     }
    280 
    281 
    282     /**
    283       * @ClassName:      NioTest1
    284       * @Description:     描述  测试 filelock
    285       * @Author:         
    286       * @CreateDate:     2019/8/27 21:30
    287       * @Version:        1.0
    288      */
    289     @Test
    290     public void testFilelock() throws Exception {
    291         FileChannel fileChannel = new RandomAccessFile("NioTest1.txt", "rw").getChannel();
    292 
    293         FileLock fileLock = fileChannel.lock(3, 6, false);
    294 
    295         System.out.println(fileLock.isValid());
    296         System.out.println(fileLock.isShared());
    297     }
    298 
    299 
    300     /**
    301       * @ClassName:      NioTest1
    302       * @Description:     描述
    303       * @Author:         
    304       * @CreateDate:     2019/8/27 22:36
    305       * @Version:        1.0
    306      */
    307     @Test
    308     public void testScattering() throws Exception {
    309         ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
    310         SocketAddress address = new InetSocketAddress(8899);
    311         serverSocketChannel.bind(address);
    312 
    313         SocketChannel socketChannel = serverSocketChannel.accept();
    314 
    315         int messageLength = 2 + 3 +4;
    316         ByteBuffer[] byteBuffers = new ByteBuffer[3];
    317 
    318         byteBuffers[0] = ByteBuffer.allocate(2);
    319         byteBuffers[1] = ByteBuffer.allocate(3);
    320         byteBuffers[2] = ByteBuffer.allocate(4);
    321 
    322         while(true) {
    323             long readLength = 0;
    324 
    325             //最大读取 messageLength 长度的字符
    326             while(readLength < messageLength ) {
    327                 long r = socketChannel.read(byteBuffers);
    328                 readLength += r;
    329 
    330                 System.out.println("byteBuffer length r is " + r);
    331                 System.out.println("readLength length r is " + readLength);
    332 
    333                 Arrays.asList(byteBuffers).forEach(byteBuffer -> {
    334                     System.out.println("p:" + byteBuffer.position() + ", l: " +byteBuffer.limit());
    335                 });
    336             }
    337 
    338             Arrays.asList(byteBuffers).forEach(byteBuffer -> {
    339                 byteBuffer.flip();
    340             });
    341 
    342             long writeLength = 0;
    343             //写会去
    344             while(writeLength < messageLength) {
    345                 long w = socketChannel.write(byteBuffers);
    346                 writeLength += w;
    347                 System.out.println("byteBuffer length w is " + w);
    348                 System.out.println("writeLength length w is " + writeLength);
    349 
    350                 Arrays.asList(byteBuffers).forEach(byteBuffer -> {
    351                     System.out.println("p:" + byteBuffer.position() + ", l: " +byteBuffer.limit());
    352                 });
    353             }
    354 
    355             Arrays.asList(byteBuffers).forEach(byteBuffer -> byteBuffer.clear());
    356 
    357         }
    358     }
    359 
    360     @Test
    361     public void testSelector() throws  Exception{
    362         Selector selector = Selector.open();
    363 
    364         int[] ports = {5000, 5001, 5002, 5003, 5004};
    365 
    366         for (int i = 0; i < ports.length; i++) {
    367             ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
    368             serverSocketChannel.configureBlocking(false); //变成非阻塞的模式 很重要
    369 
    370 //            serverSocketChannel.bind(new InetSocketAddress(ports[i]));
    371 
    372             ServerSocket serverSocket = serverSocketChannel.socket();
    373             //这个bind 直接绑在 serverSocketChannel 可以不  尝试了下,好像区别不大,都可以走通  但是不能重复绑
    374             serverSocket.bind(new InetSocketAddress(ports[i]));
    375 
    376             serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
    377 
    378             System.out.println("监听:" + ports[i]);
    379         }
    380 
    381         while(true) {
    382 
    383             int number = selector.select();
    384             System.out.println("number:" + number);
    385 
    386             Set<SelectionKey> selectionKeys = selector.selectedKeys();
    387 
    388             Iterator<SelectionKey> keyIterable = selectionKeys.iterator();
    389 
    390             System.out.println("selectionKeys : " + selectionKeys);
    391 
    392             while(keyIterable.hasNext()) {
    393                 SelectionKey selectionKey = keyIterable.next();
    394                 if(selectionKey.isAcceptable()) {//可接受的
    395                     ServerSocketChannel serverSocketChannel = (ServerSocketChannel) selectionKey.channel();
    396                     //这里为什么还要调accept  因为上面放进去的就是 ServerSocketChannel  ,而且没有调accept  接收请求
    397                     SocketChannel socketChannel = serverSocketChannel.accept();
    398                     socketChannel.configureBlocking(false);
    399 
    400                     System.out.println("获得链接:" + socketChannel);
    401 
    402                     socketChannel.register(selector, SelectionKey.OP_READ);
    403 //                    socketChannel.register(selector, SelectionKey.OP_READ);  重复注册好像不影响
    404 
    405                     keyIterable.remove();//如果不remove  selectionKeys中会一直存在事件对象
    406                 } else if(selectionKey.isReadable()) {//可读取的
    407                     //这里就可以直接用SocketChannel来接收,因为在accept中,是用socketChannel来注册的
    408                     SocketChannel socketChannel = (SocketChannel) selectionKey.channel();
    409 
    410                     ByteBuffer byteBuffer = ByteBuffer.allocate(512);
    411                     while(socketChannel.read(byteBuffer) > 0) {
    412                         byteBuffer.flip();
    413 
    414                         System.out.println("读取到客户端的消息:" + byteBuffer);
    415                         System.out.println("读取到客户端:" + socketChannel);
    416 
    417                         socketChannel.write(byteBuffer);
    418 
    419                         byteBuffer.clear();
    420                     }
    421 
    422                     keyIterable.remove();
    423 
    424                 }
    425 
    426             }
    427 
    428         }
    429 
    430 
    431     }
    432 }
  • 相关阅读:
    理解对象和对象的描述特性
    常用JS方法整理
    vue组件从开发到发布
    Mac OS X下安装Vue脚手架(vue-cli)
    前端开发中提到的“脚手架”到底指什么,CLI?gulp 和 gulp-cli有什么区别
    【Android Studio快捷键】之代码提示
    Linux安装vmtools
    VC 获取控制台窗体的句柄(hWnd)
    ym——物联网入口之中的一个Android蓝牙4.0
    Nginx 做系统的前端反向proxy
  • 原文地址:https://www.cnblogs.com/amibandoufu/p/11441542.html
Copyright © 2011-2022 走看看