重温JAVA网络编程之NIO(一)

上一篇讲到无法从根本上解决阻塞问题,但是在jdk1.4以后引入NIO类库以后,成功解决掉了这个问题。

在传统BIO中我们对每一个请求都需要一个处理,但是引入NIO以后我们可以一个线程处理多个请求。

在介绍NIO以前先介绍一些概念:

缓冲区Buffer

Buffer是一个对象,在面向流的IO中可以将数据直接读/写到Stream对象中。在NIO中所有的数据都是用缓冲区来做处理的。

事实上,缓冲区就是一个数组,但是它提供了数据的结构化访问即维护读写位置等信息。

NIO为每一个基本类型(除boolean)都提供了一个缓冲区:

他们都继承Buffer这个类,通过查看源码,Buffer有如下属性:

    private int mark = -1;        //标记,标记后的索引位置,可以通过reset()方法修改position到该位置,mark的位置要<=poition
    private int position = 0;     //下一个要读取的位置
    private int limit;            //限制,按照索引来,limit之后的不能修改,limit范围内的可以进行读写操作
    private int capacity;         //Buffer中最大容量,不能为负

常用方法:

//构造方法
 Buffer(int mark, int pos, int lim, int cap) {       // package-private
        if (cap < 0)
            throw new IllegalArgumentException("Negative capacity: " + cap);
        this.capacity = cap;
        limit(lim);
        position(pos);
        if (mark >= 0) {
            if (mark > pos)
                throw new IllegalArgumentException("mark > position: ("
                                                   + mark + " > " + pos + ")");
            this.mark = mark;
        }
    }
//通过构造方法,可以看出容量不能为负,并且mark>=0,且<position;

//设置位置
public final Buffer position(int newPosition) {
        if ((newPosition > limit) || (newPosition < 0))
            throw new IllegalArgumentException();
        position = newPosition;
        if (mark > position) mark = -1;
        return this;
    }
//position的位置必须要limit范围内,并且不能小于0,如果mark>新的postion,将mark置为-1

//设置约束
  public final Buffer limit(int newLimit) {
        if ((newLimit > capacity) || (newLimit < 0))
            throw new IllegalArgumentException();
        limit = newLimit;
        if (position > limit) position = limit;
        if (mark > limit) mark = -1;
        return this;
    }
//要求liimit小于容量,且poition>新limit时,将position设为limit的位置,同时mark也不能大于limit

//将postion还原为position
  public final Buffer reset() {
        int m = mark;
        if (m < 0)
            throw new InvalidMarkException();
        position = m;
        return this;
    }


//清空Buffer
 public final Buffer clear() {
        position = 0;
        limit = capacity;
        mark = -1;
        return this;
    }

//翻转缓冲区(读取数据的时候使用),读取完之后为写入做好准备
 public final Buffer flip() {
        limit = position;
        position = 0;
        mark = -1;
        return this;
    }
//这样做的目的是为了读出有效数据,limit为长度,从position开始读取

//重置,为重新读取做好准备
 public final Buffer rewind() {
        position = 0;
        mark = -1;
        return this;
    }

当然在他的子类中也增加了一些方法(以IntBuffer为例):

//属性
     final int[] hb;                  // 用数组进行存储
    final int offset;                 //起始位置
    boolean isReadOnly;               //是否只读标志
//常用方法
//创建方法:
 public static IntBuffer allocate(int capacity) {
        if (capacity < 0)
            throw new IllegalArgumentException();
        return new HeapIntBuffer(capacity, capacity);
    }
//这里数通过HeapIntBuffer去初始化的

//添加数据
  public IntBuffer put(IntBuffer src) {
        if (src == this)
            throw new IllegalArgumentException();
        if (isReadOnly())
            throw new ReadOnlyBufferException();
        int n = src.remaining();
        if (n > remaining())
            throw new BufferOverflowException();
        for (int i = 0; i < n; i++)
            put(src.get());
        return this;
    }

//读取数据

  public IntBuffer get(int[] dst, int offset, int length) {
        checkBounds(offset, length, dst.length);
        if (length > remaining())
            throw new BufferUnderflowException();
        int end = offset + length;
        for (int i = offset; i < end; i++)
            dst[i] = get();
        return this;
    }

//比较方法
  public boolean equals(Object ob) {
        if (this == ob)
            return true;
        if (!(ob instanceof IntBuffer))
            return false;
        IntBuffer that = (IntBuffer)ob;
        if (this.remaining() != that.remaining())
            return false;
        int p = this.position();
        for (int i = this.limit() - 1, j = that.limit() - 1; i >= p; i--, j--)
            if (!equals(this.get(i), that.get(j)))
                return false;
        return true;
    }

使用案例:

	IntBuffer buffer = IntBuffer.allocate(10);
	buffer.put(10);
        buffer.flip();
	System.out.println(buffer.position()+"  "+buffer.capacity()+"  "+buffer.limit());
	System.out.println(buffer.get(0));

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值