Java NIO Channel

来源:互联网 发布:linux 下安装jdk 编辑:程序博客网 时间:2024/06/07 05:12

Java NIO的通道类似流,但又有些不同:

  • 既可以从通道中读取数据,又可以写数据到通道。但流的读写通常是单向的。
  • 通道可以异步地读写。
  • 通道中的数据总是要先读到一个Buffer,或者总是要从一个Buffer中写入。

正如上面所说,从通道读取数据到缓冲区,从缓冲区写入数据到通道。如下图所示:
这里写图片描述

Channel的实现

这些是Java NIO中最重要的通道的实现:

  • FileChannel
  • DatagramChannel
  • SocketChannel
  • ServerSocketChannel

FileChannel 从文件中读写数据。

DatagramChannel 能通过UDP读写网络中的数据。

SocketChannel 能通过TCP读写网络中的数据。

ServerSocketChannel可以监听新进来的TCP连接,像Web服务器那样。对每一个新进来的连接都会创建一个SocketChannel。

使用FileChannel读取数据到Buffer中的示例:

package com.hutonm.nio;import org.junit.Before;import org.junit.Test;import java.io.FileNotFoundException;import java.io.IOException;import java.io.RandomAccessFile;import java.nio.ByteBuffer;import java.nio.channels.FileChannel;import java.util.RandomAccess;public class Niotest {    @Test    public void method1(){        RandomAccessFile aFile = null;        try {            aFile = new RandomAccessFile("src/nio.text","rw");            FileChannel fileChannel = aFile.getChannel();            //create buffer with capacity of 1024 bytes            ByteBuffer buf = ByteBuffer.allocate(1024);            //read into buffer            int byteRead = fileChannel.read(buf);            // print byteRead            //System.out.println(byteRead);            while (byteRead != -1){                //make buffer read for read                buf.flip();                while (buf.hasRemaining()){                    System.out.print((char)buf.get());                }                //清除已读数据                buf.compact();                byteRead = fileChannel.read(buf);            }        } catch (FileNotFoundException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        }    }}

创建一个SocketChannel:

package com.hutonm.nio;import org.junit.Test;import java.io.IOException;import java.net.InetSocketAddress;import java.nio.ByteBuffer;import java.nio.channels.SocketChannel;import java.util.concurrent.TimeUnit;public class NioClient {    @Test    public  void client(){        ByteBuffer buffer = ByteBuffer.allocate(1024);        SocketChannel socketChannel = null;        try {            socketChannel = SocketChannel.open();            socketChannel.configureBlocking(false);            socketChannel.connect(new InetSocketAddress("10.0.2.41",8080));            if(socketChannel.finishConnect()){                int i = 0;                while (true){                    TimeUnit.SECONDS.sleep(1);                    String info = "i'm " + i++ + "th information from client";                    buffer.clear();                    buffer.put(info.getBytes());                    buffer.flip();                    while (buffer.hasRemaining()){                        System.out.println(buffer);                        socketChannel.write(buffer);                    }                }            }        } catch (IOException e) {            e.printStackTrace();        } catch (InterruptedException e) {            e.printStackTrace();        }    }}

//
运行演示图:
client

java.nio.HeapByteBuffer[pos=0 lim=31 cap=1024]java.nio.HeapByteBuffer[pos=0 lim=31 cap=1024]java.nio.HeapByteBuffer[pos=0 lim=31 cap=1024]java.nio.HeapByteBuffer[pos=0 lim=31 cap=1024]java.nio.HeapByteBuffer[pos=0 lim=31 cap=1024]java.nio.HeapByteBuffer[pos=0 lim=31 cap=1024]java.nio.HeapByteBuffer[pos=0 lim=31 cap=1024]java.nio.HeapByteBuffer[pos=0 lim=31 cap=1024]

server:

======i'm 0th information from clienti'm 1th information from clienti'm 2th information from clienti'm 3th information from clienti'm 4th information from clienti'm 5th information from clienti'm 6th information from client

参考:
http://ifeve.com/channels/