Java NIO缓冲区(Buffer)实现数据的存取

1.什么是NIO

NIO 是 java New IO 的简称,在 jdk1.4 里提供的新 API。

1.   为所有的原始类型提供 (Buffer) 缓存支持。

2.   字符集编码解码解决方案。

3.   Channel:通道(一个新的原始 I/O 抽象)。

4.    支持锁和内存映射文件的文件访问接口。

5.    提供多路 (non-bloking) 非阻塞式的高伸缩性网络 I/O 。

NIO基于Channel和Buffer(缓冲区)进行操作,数据总是从通道读取到缓冲区中,或者从缓冲区写入到通道中。Selector(选择区)用于监听多个通道的事件(比如:连接打开,数据到达)。因此,单个线程可以监听多个数据通道。

2.IO与NIO的区别

IO NIO
面向Stream 面向Buffer
阻塞IO 非阻塞IO
  Selectors

3.NIO实现数据存取

从类图上可以看出都继承与Buffer类,在Buffer类中有四个重要属性:

下面就通过代码来理解Buffer的属性及方法:

package com.hmi.NIO;

import java.nio.ByteBuffer;

import org.junit.Test;

/**
 * 一.缓冲区(Buffer):在java NIO中负责存取数据,底层是数组,用于存储不同数据类型的数据
 * 
 * 根据数据类型的不同,有不同的缓冲区(Boolean除外): 
 * ByteBuffer 
 * ShortBuffer 
 * IntBuffer 
 * LongBuffer
 * FloatBuffer
 * DoubleBuffer 
 * CharBuffer 
 * 上述缓冲区都是通过allocate()获取缓冲区
 * 
 * 二. 缓冲区存取数据的两个核心方法: put()向缓冲区存储数据  get()从缓冲区中取数据
 * 
 * 三.缓冲区的核心属性: 
 * capacity:缓冲区存储数据的最大容量,一旦声明不能改变(底层为数组)。
 * limit:缓冲区的界限,表示可以操控数据的大小,即limit后面的1数据不能进行读写。
 * position:缓冲区正在操控数据的位置。
 * mark:标记position,使用reset()方法后重新回到该位置。 
 * mark <= position <= limit <= capacity
 */
public class BufferTest {

	@Test
	public void Test1() {
		// 分配一个指定大小的缓冲区
		ByteBuffer buf = ByteBuffer.allocate(1024);
		String str = "abcde";

		// 1.调用put()方法,往缓冲区里存数据
		buf.put(str.getBytes());
		System.out.println("调用put()方法,往缓冲区存数据后:");
		System.out.println("-------------------");
		System.out.println("缓冲区当前的最大容量:" + buf.capacity());
		System.out.println("缓冲区当前的最大界限:" + buf.limit());
		System.out.println("缓冲区当前的操作位置:" + buf.position());
		System.out.println("-------------------");

		// 2.调用flip()方法,切换为读数据模式
		buf.flip();
		System.out.println("调用flip()方法,切换为读数据模式后:");
		System.out.println("-------------------");
		System.out.println("缓冲区当前的最大容量:" + buf.capacity());
		System.out.println("缓冲区当前的最大界限:" + buf.limit());
		System.out.println("缓冲区当前的操作位置:" + buf.position());
		System.out.println("-------------------");

		// 3.调用get()方法,读取缓冲区数据
		byte[] dst = new byte[buf.limit()];
		buf.get(dst);
		System.out.println("调用get()方法,读取缓冲区数据后:");
		System.out.println("缓冲区里的数据为:" + new String(dst, 0, dst.length));
		System.out.println("-------------------");
		System.out.println("缓冲区当前的最大容量:" + buf.capacity());
		System.out.println("缓冲区当前的最大界限:" + buf.limit());
		System.out.println("缓冲区当前的操作位置:" + buf.position());
		System.out.println("-------------------");

		// 4.调用clear()方法,清空缓冲区,但缓冲区里的数据任然存在,处于"被遗忘"状态
		buf.clear();
		System.out.println("调用clear()方法,清空缓冲区后:");
		System.out.println("缓冲区里的数据为:" + new String(dst, 0, dst.length));
		System.out.println("-------------------");
		System.out.println("缓冲区当前的最大容量:" + buf.capacity());
		System.out.println("缓冲区当前的最大界限:" + buf.limit());
		System.out.println("缓冲区当前的操作位置:" + buf.position());
		System.out.println("-------------------");
	}

	@Test
	public void Test2() {
		// 1.分配一个指定大小的缓冲区
		ByteBuffer buf = ByteBuffer.allocate(1024);
		String str = "abcde";
		// 2.往缓冲区中添加数据
		buf.put(str.getBytes());
		// 3.切换为读取数据模式
		buf.flip();
		// 定义字节数组存放数据
		byte[] dst = new byte[buf.limit()];
		// 取前两位数据,并转换为字符串输出
		buf.get(dst, 0, 2);
		System.out.println("缓冲区前两位的数据为:" + new String(dst, 0, 2));
		System.out.println("缓冲区当前的操作位置:" + buf.position());
		// 4.标记当前position
		buf.mark();
		// 取后三位数据,并转换为字符串输出
		buf.get(dst, 2, 3);
		System.out.println("缓冲区后三位的数据为:" + new String(dst, 2, 3));
		System.out.println("缓冲区当前的操作位置:" + buf.position());
		// 5,使用reset(),重置position为标记位置
		buf.reset();
		System.out.println("经过reset()后,缓冲区的操作位置:" + buf.position());
	}
}

Test1()运行结果:

Test2()运行结果:

猜你喜欢

转载自blog.csdn.net/hm_135/article/details/105097733