Buffer
Buffer没有构造函数,只能通过static XxxBuffer allocate(int capacity) 来创建一个容量为capacity的XxxBuffer.
packagecom.ivy.nio;importjava.nio.CharBuffer;public classBufferDemo {public static voidmain(String[] args) {//TODO Auto-generated method stub
CharBuffer buffer= CharBuffer.allocate(8);
System.out.println("capacity:" +buffer.capacity());
System.out.println("limit:" +buffer.limit());
System.out.println("position:" +buffer.position());
buffer.put("a");
buffer.put("b");
buffer.put("c");
System.out.println("after adding three elements -------");
System.out.println("position:" +buffer.position());
buffer.flip();
System.out.println("after flip -------");
System.out.println("position:" +buffer.position());
System.out.println("position(0):" +buffer.get());
System.out.println("position:" +buffer.position());
buffer.clear();
System.out.println("after clear -------");
System.out.println("limit:" +buffer.limit());
System.out.println("position:" +buffer.position());
System.out.println("position(2):" + buffer.get(2));
System.out.println("position:" +buffer.position());
}
}
三个重要概念,容量,界限,位置:
容量(capacity):缓冲区的容量,最多可以存多少数据。
界限(limit):第一个不应该被读出或写入的缓冲区位置索引,也就是说,位于limit后的数据既不可读,也不可写。
位置(position):用于指明下一个可以被读出的或写入到缓冲区位置索引,当读数据时,positon的值恰好等于已经读了多少数据。
当Buffer装入数据解暑后,调用Buffer的flip方法,该方法将limit设置为position所在的位置,将position设为0,这样buffer就为输出数据做好了准备;当Buffer输出数据结束后,Buffer调用clear方法,它并不是清空数据,仅仅将position位置置为0,将limit置为capacity,这样为再次向Buffer中装入数据做好准备。
使用Channel
Channel类似于传统的流对象,但与传统的流对象有两个主要区别:
Channel可以直接将制定文件的部分或全部直接映射成Buffer。
程序不能直接访问Channel的数据,包括读取,写入都不行,Channel只能与Buffer进行交互。
所有的Channel都不应该通过构造器来直接创建,而是通过传统的节点InputStream,OutputStream的getChannel方法来返回对应的Channel,不同的节点流获得的Channel不一样。
Channel中最常用的3个方法是map(), read()和write(). map()方法的方法签名为:MappedByteBuffer map(FileChannel.MapMode mode, long position, long size). 第一个参数执行映射时的模式,分别有只读/读写等模式,第二第三个参数用于控制将Channel的哪些数据映射成ByteBuffer。
packagecom.ivy.nio;importjava.io.File;importjava.io.FileInputStream;importjava.io.FileOutputStream;importjava.io.IOException;importjava.nio.CharBuffer;importjava.nio.MappedByteBuffer;importjava.nio.channels.FileChannel;importjava.nio.charset.Charset;importjava.nio.charset.CharsetDecoder;public classFileChannelDemo {public static voidmain(String[] args) {//TODO Auto-generated method stub
File f= new File("./src/com/ivy/nio/FileChannelDemo.java");try(
FileChannel inChannel= newFileInputStream(f).getChannel();
FileChannel outChannel= new FileOutputStream("channelOutput.txt").getChannel()) {
MappedByteBuffer buffer= inChannel.map(FileChannel.MapMode.READ_ONLY, 0, f.length());
Charset charset= Charset.forName("GBK");
outChannel.write(buffer);
buffer.clear();
CharsetDecoder decoder=charset.newDecoder();
CharBuffer charBuffer=decoder.decode(buffer);
System.out.println(charBuffer);
}catch(IOException ioe) {
ioe.printStackTrace();
}
}
}
packagecom.ivy.nio;importjava.io.File;importjava.io.IOException;importjava.io.RandomAccessFile;importjava.nio.MappedByteBuffer;importjava.nio.channels.FileChannel;public classRandomFileChannelDemo {public static voidmain(String[] args) {//TODO Auto-generated method stub
File f= new File("channelOutput.txt");try(
RandomAccessFile raf= new RandomAccessFile(f, "rw");
FileChannel randomChannel=raf.getChannel();) {
MappedByteBuffer buffer= randomChannel.map(FileChannel.MapMode.READ_ONLY, 0, f.length());
randomChannel.position(f.length());
randomChannel.write(buffer);
}catch(IOException ioe) {
ioe.printStackTrace();
}
}
}
Charset
packagecom.ivy.nio;importjava.nio.ByteBuffer;importjava.nio.CharBuffer;importjava.nio.charset.Charset;importjava.nio.charset.CharsetDecoder;importjava.nio.charset.CharsetEncoder;public classCharsetTransformDemo {public static void main(String[] args) throwsException {//TODO Auto-generated method stub
Charset cn= Charset.forName("GBK");
CharsetEncoder cnEncoder=cn.newEncoder();
CharsetDecoder cnDecoder=cn.newDecoder();
CharBuffer cBuffer= CharBuffer.allocate(8);
cBuffer.put("孙");
cBuffer.put("悟");
cBuffer.put("空");
cBuffer.flip();
ByteBuffer bBuffer=cnEncoder.encode(cBuffer);for (int i = 0; i < bBuffer.capacity(); i++) {
System.out.print(bBuffer.get(i)+ " ");
}
System.out.println("\n" +cnDecoder.decode(bBuffer));
}
}
实际上,Charset类也提供了decode(ByteBuffer bb), encode(CharBuffer cb)和encode(String str),也就是说,获取了Charset对象后,如果仅仅需要进行简单的编码解码操作,其实无须创建CharsetEncoder & CharsetDecoder,直接调用Charst的encode和decode方法进行编码和解码就行。
文件锁
在NIO中,Java提供了FileLock来支持文件锁。