【JAVA】【NIO】对系列翻译的总结,一个综合实例的分析,网络服务端接收客户端输入,实时将内容写文件

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://xxlcube.blog.csdn.net/article/details/44587569

基于前面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);
			}
		}
		
		
	}

}





对于代码中的任何问题,欢迎留言,望各位读者不吝指教!!

展开阅读全文

没有更多推荐了,返回首页