<span style="font-size:24px;">JAVA的新IO添加了两个核心对象:Channel(通道)和Buffer(缓冲)。</span>
Channel相当于前面学过的InputStream和OutputStream,不过它可以通过map方法可以直接将“一块数据”映射到内存,而Buffer其实更像一个数组,发送到Channel的所有对象都必须先经过Buffer,下面是对它们俩的一些学习。
1.使用Buffer
Buffer是一个抽象类,有许多子类,CharBuffer,IntBuffer,ByteBuffer等等,从名字就知道它们所存储的数据类型,使用最多的是CharBuffer和ByteBuffer
(2)Buffer有三个重要的概念。
容量(capacity):它是Buffer的最大的数据容量
界限(limite):就是说在limite后面的数据就无法进行操作了
位置(position):指明下一个可以被读出或写入的缓冲区位置索引。Buffer刚建立时,position=0;
Buffer的作用就是装入数据和读取数据。在初始化Buffer时就需要确定capacity,Buffer在装入数据时,position会自动的往后移动。当调用flip()后,limit=position,而position=0,即系统为读取数据做准备。而当调用clear()后,limit=capacity,position=0,即为装入数据做准备。需要注意的是,在调用clear()后,系统并不清空Buffer,也即是Buffer的数据依然存在
下面的程序的输出很好的说明了Buffer装入和读取数据的过程:
package bufferTest;
import java.nio.CharBuffer;
public class BufferTest {
public static void main(String args[]){
//create a buffer with 8 capaity
CharBuffer cbuff=CharBuffer.allocate(8);
System.out.println("Capacity:"+cbuff.capacity());
System.out.println("Limit:"+cbuff.limit());
System.out.println("position:"+cbuff.position());
cbuff.put("a");
cbuff.put("b");
cbuff.put("c");
System.out.println("Capacity2:"+cbuff.capacity());
System.out.println("Limit2:"+cbuff.limit());
System.out.println("position2:"+cbuff.position());
//perpare to get data
cbuff.flip();
System.out.println("after flip Capacity:"+cbuff.capacity());
System.out.println("after flip Limit:"+cbuff.limit());
System.out.println("position=0:"+cbuff.get());
System.out.println("after get a char Limit:"+cbuff.position());
//reset and perpare to put data
cbuff.clear();
System.out.println("Limit2:"+cbuff.limit());
System.out.println("position2:"+cbuff.position());
System.out.println("position=0:"+cbuff.get(2));
System.out.println("position2:"+cbuff.position());
}
}
输出:Capacity:8 Limit:8 position:0
Capacity2:8 Limit2:8 position2:3
after flip Capacity:8 after flip Limit:3
position=0:a
after get a char Limit:1
Limit2:8 position2:0 position=0:c
position2:0
2.使用channel
Channel类似于传统的流对象,但与流对象有两个主要的差别:
(1)Channel可以将指定文件的全部或部分直接映射为Buffer
(2)程序不能直接访问Channel,Channel只能与Buffer进行交互
下面的程
package channelTest;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.nio.MappedByteBuffer;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.charset.CharsetDecoder;
import java.nio.CharBuffer;
public class FileChannelTest {
public static void main(String args[]){
FileChannel inChannel=null;
FileChannel outChannel=null;
try{
File f=new File("b.txt");
//get channel
inChannel=new FileInputStream(f).getChannel();
//from channel to bytebuffer
MappedByteBuffer mbbuff=inChannel.map(FileChannel.MapMode.READ_ONLY, 0, f.length());
//use GBK create a charset
Charset cs=Charset.forName("GBK");
outChannel=new FileOutputStream("a.txt").getChannel();
outChannel.write(mbbuff);
mbbuff.clear();
//create a decoder
CharsetDecoder csDecoder=cs.newDecoder();
//from byte to char as so can show
CharBuffer cbuff=csDecoder.decode(mbbuff);
System.out.println(cbuff);
}
catch(Exception e){e.printStackTrace();}
finally{
try{
if(inChannel!=null){inChannel.close();}
if(outChannel!=null){outChannel.close();}
}
catch(Exception ex){ex.printStackTrace();}
}
}
}
序是将FileChannel的全部数据映射为ByteBuffer的效果:
其中最重要的就是map()方法了。