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 client
i'm 1th information from client
i'm 2th information from client
i'm 3th information from client
i'm 4th information from client
i'm 5th information from client
i'm 6th information from client