讲到NIO 不妨从老的IO 说起。
老的I/O 核心接口有2个: 一个是 InputStream/OutputStream (字节流),一次处理一个字节,Reader/Writer (字符流) ,一次处理一个字符。
NIO 是从JDK 1.4 才有的,她最基本的数据类型是Channel 和Buffer.
Channel表示数据的源头或者目的地,用于向Buffer提供数据或者读取Buffer的数据。
Buffer是一个连续的内存块,是NIO数据读写的中转地.
NIO有7种基本的Buffer类型,每种类型对应一个基本类型。
Buffer的结构包含3个变量
position: 读操作时(当前读的位置) / 写操作时(写了多少)
limit: 读操作时候(最多能读多少,等同于已经写的量) /写操作时候(最多能写多少,等同于整个buffer的容量)
capacity: 读操作时候(buffer容量) / 写操作时候(buffer容量)
Buffer的常见方法:
flip(): 在读模式和写模式之间进行切换
clear():清空Buffer
以下是一些小例子:
(1) NIO 从网络上读内容 ,我们这里演示从Baidu 上读取内容
- /**
- * @author charles.wang
- * @created Mar 9, 2011 10:31:35 AM
- * Description:
- */
- public class BaiduReader {
- private Charset charset=Charset.forName("GBK");//创建GBK字符集
- private SocketChannel channel;
- public void readHTMLContext(){
- try{
- System.out.println("Start reading the HTML context...");
- InetSocketAddress socketAddress = new InetSocketAddress ("www.baidu.com",80);
- //Step 1: 打开连接,创建一个基于InetSocketAddress的SocketChannel
- //SocketChannel 是4种Channel中的一种
- channel = SocketChannel.open(socketAddress);
- //Step 2:发送请求,使用GBK编码
- channel.write(charset.encode("GET "+"/ HTTP/1.1"+"\r\n\r\n"));
- //Step 3:读取数据
- ByteBuffer buffer =ByteBuffer.allocate(1024); //创建1024字节的缓冲区
- //读取过程,直到读到文件的结尾
- while(channel.read(buffer) != -1 ){
- System.out.println(1);
- buffer.flip();//buffer从写模式切换到读模式
- //打印出字符编码之后的文字
- System.out.println(charset.decode(buffer));
- buffer.clear();//清空缓冲区
- }
- }catch(IOException ex){
- System.err.println(ex.toString());
- }finally{
- if(channel != null){
- try{
- channel.close();
- }catch(IOException e){
- e.printStackTrace();
- }
- }
- }
- }
- /**
- * @param args
- */
- public static void main(String[] args) {
- // TODO Auto-generated method stub
- new BaiduReader().readHTMLContext();
- }
- }
(2)采用NIO来进行基于块的复制文件
- /**
- * @author charles.wang
- * @created Mar 9, 2011 10:00:37 AM
- * Description:
- */
- public class CopyFile {
- /**
- * @param args
- */
- public static void main(String[] args)throws Exception {
- // TODO Auto-generated method stub
- String infile="d:\\copyfrom.txt";
- String outfile="d:\\copyto.txt";
- //获取源文件和目标文件的输入输出流
- FileInputStream fin = new FileInputStream(infile);
- FileOutputStream fout = new FileOutputStream(outfile);
- //获取输入输出channel
- //可以通过一个输入输出流来获取一个相应的通道
- FileChannel fcin = fin.getChannel();
- FileChannel fcout=fout.getChannel();
- //创建缓冲区
- ByteBuffer buffer = ByteBuffer.allocate(1024);
- while(true){
- //clear方法重设缓冲区,使得它可以接受读入的数据
- buffer.clear();
- //从输入通道将数据读到缓冲区
- int r = fcin.read(buffer);
- //read 方法返回读取的字节数,可能为0,如果它已经能够到达流的末尾,那么返回-1
- if(r==-1)
- break;
- //flip方法可以让缓冲区将新读入的数据写入到另外一个通道
- buffer.flip();
- //将数据写入到fcout的通道
- fcout.write(buffer);
- }
- }
- }
本文转自 charles_wang888 51CTO博客,原文链接:http://blog.51cto.com/supercharles888/840636,如需转载请自行联系原作者