基于前面12节的一个JAVA NIO的系列翻译,本文将结合所翻译的内容,用一个综合实例来分析,让大家有一个直观的理解。首先这里贴出系列翻译的文章:
Java NIO系列翻译,唯有分享,方能进步
========================================================
【JAVA】【NIO】1、Java NIO Tutorial
http://blog.csdn.net/simonchi/article/details/44260795
原文链接:http://tutorials.jenkov.com/java-nio/index.html
【JAVA】【NIO】2、Java NIO Overview
http://blog.csdn.net/simonchi/article/details/44262257
原文链接:http://tutorials.jenkov.com/java-nio/overview.html
【JAVA】【NIO】3、Java NIO Channel
http://blog.csdn.net/simonchi/article/details/44279483
原文链接:http://tutorials.jenkov.com/java-nio/channels.html
【JAVA】【NIO】4、Java NIO Buffer
http://blog.csdn.net/simonchi/article/details/44309099
原文链接:http://tutorials.jenkov.com/java-nio/buffers.html
【JAVA】【NIO】5、Java NIO Scatter / Gather
http://blog.csdn.net/simonchi/article/details/44342311
原文链接:http://tutorials.jenkov.com/java-nio/scatter-gather.html
【JAVA】【NIO】6、Java NIO Channel to Channel Transfers
http://blog.csdn.net/simonchi/article/details/44408717
原文链接:http://tutorials.jenkov.com/java-nio/channel-to-channel-transfers.html
【JAVA】【NIO】7、Java NIO Selector
http://blog.csdn.net/simonchi/article/details/44416661
原文链接:http://tutorials.jenkov.com/java-nio/selectors.html
【JAVA】【NIO】8、Java NIO FileChannel
http://blog.csdn.net/simonchi/article/details/44488733
原文链接:http://tutorials.jenkov.com/java-nio/file-channel.html
【JAVA】【NIO】9、Java NIO SocketChannel
http://blog.csdn.net/simonchi/article/details/44493617
原文链接:http://tutorials.jenkov.com/java-nio/socketchannel.html
【JAVA】【NIO】10、Java NIO ServerSocketChannel
http://blog.csdn.net/simonchi/article/details/44494597
原文链接:http://tutorials.jenkov.com/java-nio/server-socket-channel.html
【JAVA】【NIO】11、Java NIO DatagramChannel
http://blog.csdn.net/simonchi/article/details/44560587
原文链接:http://tutorials.jenkov.com/java-nio/datagram-channel.html
【JAVA】【NIO】12、Java NIO Pipe
http://blog.csdn.net/simonchi/article/details/44563103
原文链接:http://tutorials.jenkov.com/java-nio/pipe.html
=========================================================
首先来看一个图
Selector是一个选择器,所有通道都要在这个选择器上注册相应的事件,handle是一个处理器,参数未ServerSocketChannel和SelectionKey,根据key做不同的逻辑处理,最终通过FileChannel将从客户端读取的内容实时的按字节写到文件里。
package net;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.util.Iterator;
import java.util.Set;
public class ServerSocketChannelDemo {
private static Selector selector = null;
private static Charset charset = Charset.forName("UTF-8");
//具体参照FileChannel:http://blog.csdn.net/simonchi/article/details/44488733
public static void writeFile(String fileDir,String fileName,ByteBuffer buffer) {
if(fileDir==null|fileDir.length()==0) {
fileDir = new File("").getAbsolutePath();
}
if(fileDir.endsWith("\\")||fileDir.endsWith("/")) {
fileDir = fileDir.substring(0,fileDir.length()-1);
}
RandomAccessFile raf = null;
FileChannel channel = null;
try {
raf = new RandomAccessFile(fileDir+File.separator+fileName, "rw");
channel = raf.getChannel();
//buffer.flip();
while(buffer.hasRemaining()) {
//将写入的位置定位在文件大小的最后面,相当于追加文件内容
channel.position(channel.size());
channel.write(buffer);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
channel.close();
raf.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void handle(ServerSocketChannel server,SelectionKey key) throws Exception {
if(key.isAcceptable()) {
//建立连接通道
SocketChannel sc = server.accept();
sc.configureBlocking(false);
//注册,收到连接请求,建立通道,处理后续数据
sc.register(selector, SelectionKey.OP_READ);
//将此key对应的channel设置为准备接收其它客户端请求
key.interestOps(SelectionKey.OP_ACCEPT);
sc.write(charset.encode("Connected !"));
}else if(key.isReadable()) {//处理对客户端数据的读取请求
SocketChannel sc = (SocketChannel) key.channel();
ByteBuffer buffer = ByteBuffer.allocate(1);
//StringBuffer sb = new StringBuffer();
while(sc.read(buffer)>0) {
buffer.flip();
writeFile("e:", "demo.txt", buffer);
//sb.append(charset.decode(buffer));
}
//System.out.println(sb.toString());
key.interestOps(SelectionKey.OP_READ);
}
}
public static void main(String[] args) throws Exception {
//打开服务套接字通道
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
//服务套接字通道模式设置为非阻塞
serverSocketChannel.configureBlocking(false);
//绑定服务端口
serverSocketChannel.bind(new InetSocketAddress(8090));
//打开选择器
selector = Selector.open();
//服务端套接字通道在该选择器上注册事件,接收请求
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
while(true) {
//获取在该选择器上注册的且已经就绪的通道数量
int readyChannels = selector.select();
if(readyChannels==0) {
continue;
}
Set<SelectionKey> selectedKeys = selector.selectedKeys();
Iterator<SelectionKey> keyIterator = selectedKeys.iterator();
while(keyIterator.hasNext()) {
SelectionKey key = keyIterator.next();
keyIterator.remove();
handle(serverSocketChannel,key);
}
}
}
}
对于代码中的任何问题,欢迎留言,望各位读者不吝指教!!