码迷,mamicode.com
首页 > 其他好文 > 详细

IO与NIO

时间:2016-10-22 21:04:00      阅读:291      评论:0      收藏:0      [点我收藏+]

标签:system   表示   return   ace   大数据   nbsp   stream   void   cep   

NIO简单来讲就是new IO,核心是一个接口两个抽象类,interface Channel、abstract class Buffer、abstract class Charset 。

1.Buffer最常用的两个子类是ByteBuffer、charBuffer。Buffer中有三个重要的概念:capacity(容量)、limit(界限)、position(位置):

capacity,缓冲区的容量表示该Buffer的最大数据容量,即最多可以存储多少数据,Buffer对象创建后,capacity不能改变,例如 ByteBuffer bbuff=ByteBuffer.allocate(8);  CharBuffer cbuff=CharBuffer.allocate(8);

另外两个概念limit、position 则参考Buffer的flip()方法,clear()方法的源码与注释理解:

 

/**
	 * Flips this buffer. The limit is set to the current position and then the
	 * position is set to zero. If the mark is defined then it is discarded.
	 *
	 * <p>
	 * After a sequence of channel-read or <i>put</i> operations, invoke this
	 * method to prepare for a sequence of channel-write or relative <i>get</i>
	 */
	public final Buffer flip() {
		limit = position;
		position = 0;
		mark = -1;
		return this;
	}

flip()方法为从Buffer中取数据做好准备,把limit设到原来position所在位置,这样相当于把Buffer中没有数据的存储空间挡住了,从而避免读到null。

 

 

/**
	 * Clears this buffer. The position is set to zero, the limit is set to the
	 * capacity, and the mark is discarded.
	 *
	 * <p>
	 * Invoke this method before using a sequence of channel-read or <i>put</i>
	 *
	 * <p>
	 * This method does not actually erase the data in the buffer, but it is
	 * named as if it did because it will most often be used in situations in
	 * which that might as well be the case.
	 * </p>
	 */
	public final Buffer clear() {
		position = 0;
		limit = capacity;
		mark = -1;
		return this;
	}

clear()方法为再次向Buffer中装入数据做好准备,Buffer中的原来的数据还在,没有被删除。

 

2.Channel的常用实现类为FileChannel,此实现类最常用的方法有MappedByteBuffer map(MapMode mode, long position, long size)、read()的一系列重载、write()的一系列重载方法:

FileChannel对象不是由构造器产生的,而是由FileInputStream、FileOutputStream的getChannel()产生的:

 

@Test
	public void testFileChannel() throws IOException, InterruptedException {
		File f = new File("src/main/resources/b.txt");
		// 通过fileInputStream.getChannel()方法得到FileChannel对象
		FileChannel inChannel = new FileInputStream(f).getChannel();
		/**
		 * 程序不能直接访问FileChannel中的数据,包括读取、写入都不行,FileChannel只能与MappedByteBuffer(
		 * ByteBuffer的子类)进行交互。
		 */
		// FileChannel可以将指定文件的部分或全部直接映射成ByteBuffer
		ByteBuffer bbuff = inChannel.map(MapMode.READ_ONLY, 0, f.length());
		// 通过fileOutputStream.getChannel()方法得到FileChannel对象
		FileChannel outChannel = new FileOutputStream("src/main/resources/b2.txt").getChannel();
		outChannel.write(bbuff);
	}

3.Charset主要来处理ByteBuffer和CharBuffer(或字符串,CharBuffer对象的toString()方法可以获取对应的字符串)之间的转换。利用Charset的静态方法forName(String charsetName)来获取Charset对象,之后,就可以起通过该对象的newDecoder()、newEncoder()这两个方法分别返回CharsetDecoder和CharsetEncoder对象,代表该Charset的解码器和编码器。调用CharsetDecoder的decode()方法可以将ByteBuffer转换成CharBuffer,调用CharsetEncoder的encode()方法可以将CharBuffer或者String转换成byteBuffer。

 

Charset charset = Charset.forName("UTF-8");
CharBuffer cbuff = charset.decode(bbuff);
System.out.println(cbuff);

decode()方法的参数是ByteBuffer对象,怎么获得呢?由FileChannel对象的map(MapMode mode, long position, long size)方法获得。FileChannel对象怎么获得呢?FileInputStream对象的getChannel()方法获得,而FileInputStream与最终处理的文件有关系。



 

IO与NIO

标签:system   表示   return   ace   大数据   nbsp   stream   void   cep   

原文地址:http://www.cnblogs.com/koushr/p/5873386.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!