欢迎使用优快云-markdown编辑器

Java NIO 的原理以及实例

在Java1.4之前的I/O系统中,提供的都是面向流的I/O系统,系统一次一个字节地处理数据,一个输入流产生一个字节的数据,一个输出流消费一个字节的数据,面向流的I/O速度非常慢,而在Java 1.4中推出了NIO,这是一个面向块的I/O系统,系统以块的方式处理处理,每一个操作在一步中产生或者消费一个数据库,按块处理要比按字节处理数据快的多。

NIO中的三个重要概念,通道,缓冲区,选择器

  • 通道

    • 类似于流,但是可以异步的读取数据(流只能同步写入),通道是双向的,(流是单向的),通道的数据是要先读到一个buffer或者从一个buffer写入,即通道与buffer进行数据交互。
      通道类型
      • FileChannnel : 从文件中读写数据(比较特殊,可以与通道进行数据交互,不能切换到非阻塞模式,套接字通道可以接换到非阻塞模式)
      • DatagramChannnel : 能通过UDP读写网络中的数据
      • SocketChannel : 能通过TCP读取网络中的数据
      • ServerSocketChannnel : 可以监听新进来的TCP连接,想web服务器那样,对每一个进来的连接都会创建一个SocketChannel
  • 缓冲区:本质上是一块可以存储数据的内存,被封装成了buffer对象而已!

    • 缓冲区类型

      • ByteBuffer  
      • MappedByteBuffer 用于表示内存映射文件 
      • CharBuffer  
      • DoubleBuffer  
      • FloatBuffer  
      • IntBuffer  
      • LongBuffer  
      • ShortBuffer
    • 常用方法

      • allocate() - 分配一块缓冲区  
      • put() - 向缓冲区写数据
      • get() - 向缓冲区读数据  
      • filp() - 将缓冲区从写模式切换到读模式  
      • clear() - 从读模式切换到写模式,不会清空数据,但后续写数据会覆盖原来的数据,即使有部分数据没有读,也会被遗忘;  
      • compact() - 从读数据切换到写模式,数据不会被清空,会将所有未读的数据copy到缓冲区头部,后续写数据不会覆盖,而是在这些数据之后写数据
      • mark() - 对position做出标记,配合reset使用
      • reset() - 将position置为标记值    
        缓冲区的一些属性:
      • capacity - 缓冲区大小,无论是读模式还是写模式,此属性值不会变;
      • position - 写数据时,position表示当前写的位置,每写一个数据,会向下移动一个数据单元,初始为0;最大为capacity - 1,切换到读模式时,position会被置为0,表示当前读的位置
      • limit - 写模式下,limit 相当于capacity 表示最多可以写多少数据,切换到读模式时,limit 等于原先的position,表示最多可以读多少数据。 
  • 选择器:相当于一个观察者,用来监听通道感兴趣的事件,一个选择器可以绑定多个通道

    • 通道向选择器注册时,需要指定感兴趣的事件,选择器支持以下事件:
      • SelectionKey.OP_CONNECT
      • SelectionKey.OP_ACCEPT
      • SelectionKey.OP_READ
      • SelectionKey.OP_WRITE  
    • 如果你对不止一种事件感兴趣,那么可以用“位或”操作符将常量连接起来,如下:
      • int interestSet = SelectionKey.OP_READ | SelectionKey.OP_WRITE;
          通道向选择器注册时,会返回一个 SelectionKey对象,具有如下属性
      • interest集合
      • ready集合  
      • Channel  
      • Selector
      • 附加的对象(可选)  
          用“位与”操作interest 集合和给定的SelectionKey常量,可以确定某个确定的事件是否在interest 集合中。
          ready 集合是通道已经准备就绪的操作的集合。在一次选择(Selection)之后,你会首先访问这个ready set。Selection将在下一小节进行解释。可以这样访问ready集合:
          int readySet = selectionKey.readyOps();
          也可以使用以下四个方法获取已就绪事件,返回值为boolean:
        selectionKey.isAcceptable();
        selectionKey.isConnectable();
        selectionKey.isReadable();
        selectionKey.isWritable();
          可以将一个对象或者更多信息附着到SelectionKey上,即记录在附加对象上,方法如下:
        selectionKey.attach(theObject);
        Object attachedObj = selectionKey.attachment();
          可以通过选择器的select方法获取是否有就绪的通道;
        ○ int select()  
        ○ int select(long timeout)  
        ○ int selectNow()
          返回值表示上次执行select之后,就绪通道的个数。 
          可以通过selectedKeySet获取已就绪的通道。返回值是SelectionKey 的集合,处理完相应的通道之后,需要removed 因为Selector不会自己removed
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值