首页 > 代码库 > IO与NIO
IO与NIO
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