`
wdt1988520
  • 浏览: 15430 次
社区版块
存档分类
最新评论

JAVA NIO

 
阅读更多

Java SE1.4引入了大量用于改进输入/输出处理机制的特性

 

NIO的特性:

1、字符集编码器和解码器

2、非阻塞的I/O

3、内存映射文件

4、文件加锁机制

 

    大多数操作系统都可以利用虚拟内存实现将一个文件或者文件的一部分“映射”到内存中。然后就可以像内存一样访问快速。

JAVA NIO中提供了访问内存映射的方式“通道(channel)”传递,通道是用户磁盘文件的一种抽象,提供访问诸如内存映射、文件加锁机制以及文件间快速数据等操作系统特性。

 

谈谈:非阻塞IO几个组成部分

 1、Buffer

         ByteBuffer、CharBuffer、ShortBuffer、IntBuffer、LongBuffer、FloatBuffer、DoubleBuffer

 2、Channel

         FileChannel、DataGramaChannel、SocketChannel、ServerSocketChannel

 3、CharSet

         CharEncoder、CharDecoder

 4、Selector

      Selector运行单线程处理多个Channel,要使用Selector需要向它注册Channel。

      Selector源码中它维护了一个集合(SelectionKey),它分别有以下状态:

      //一个是已注册的registedKeys(它里面是SelectionKey集合)集合

      //一个是已选择的selectedKeys集合

      //一个是已取消但未解除注册的cancelledKeys集合

      SelectionKey维护了两个对象(感兴趣时间、Channel)

      //SelectionKey是channel和Selector的关联对象

      //SelectionKey维护了两个Set集合,一个是感兴趣事件,一个是准备好并可以执行I/O操作的Channel

 

 

简单的例子

    

package nio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
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.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
import java.util.Iterator;

/**
 *服务器端
 *1、创建编码方式 CharSet 
 *2、创建Selector
 *3、创建服务SocketChannel
 */
public class NioServer {
    //服务器端口 
	int port=9999;
	//编码器
	CharsetEncoder encoder=Charset.forName("GB2312").newEncoder();
	//解码器
	CharsetDecoder decoder=Charset.forName("GB2312").newDecoder();
	//通道选择器
	Selector selector;
	//服务器socket通道
	ServerSocketChannel channel;
	//缓存 指定数据块为1024
	ByteBuffer buffer=ByteBuffer.allocate(1024);
	
	
	/**
	 * 
	 * 打开选择器
	 * @throws IOException 
	 */
	public void initSelector() throws IOException{
		selector=Selector.open();
	}
	
	/**
	 * 
	 * 初始化服务器
	 * @throws IOException 
	 */
	public void initServer() throws IOException{
		channel=ServerSocketChannel.open();
		channel.socket().bind(new InetSocketAddress(port));
		//设置服务socket为非阻塞方式
		channel.configureBlocking(false);
		//注册channel到selector
		channel.register(selector, SelectionKey.OP_ACCEPT);
	}
     
	/**
	 * 
	 * 监听Selector对channel的选择
	 * 循环监听
	 */
	public void listen(){
		System.out.println("监听-----9999");
		for(;;){
			try {
				//执行select操作对channel通道的选择
				//每次选出就绪(及有数据读取、写出)的通道
				//但返回的对象为SelectionKeys
				selector.select();
				Iterator<SelectionKey> keys=selector.selectedKeys().iterator();
				while(keys.hasNext()) {
					SelectionKey key=keys.next();
					if(key.isAcceptable()){
						//可以选择的channel
						channel=(ServerSocketChannel) key.channel();
						//接到客户端的socket
						SocketChannel client=channel.accept();
						//设置客户端socket通道为非阻塞方式
						client.configureBlocking(false);
						//客户端socket设置为对读取数据感兴趣
						client.register(selector, SelectionKey.OP_READ);
					}else if(key.isReadable()){
						SocketChannel client=(SocketChannel) key.channel();
						//读取数据到buffer中
						if(client.read(buffer)>0){
							 //反转数据,及把buffer的指针指回0,从头开始读取数据
						     buffer.flip();
						     CharBuffer charBuffer=decoder.decode(buffer);
						     System.out.println("读取到的数据:"+charBuffer.toString());
						     //将clientsocket注册为写事件
						     client.register(selector, SelectionKey.OP_WRITE);
						     //将获取的附加在SelectionKey中,以便下次使用,每一次将覆盖下一次。
						     key.attach(charBuffer.toString());
						}else{
							//没有数据则关闭通道
							client.close();
						}
						buffer.clear();
					}else if(key.isWritable()){
						SocketChannel client=(SocketChannel) key.channel();
						//想客户端写数据
						client.write(encoder.encode(CharBuffer.wrap("欢迎访问服务器"+key.attachment())));
						client.close();
					}
				}
				//为了在下一次select操作中,更新selectionKey 必须的操作
				keys.remove();
			} catch (IOException e) {
				
				e.printStackTrace();
			}
		}
	}
	
	public static void main(String[] args) {
		NioServer server=new NioServer();
		try {
			server.initSelector();
			server.initServer();
			server.listen();
		} catch (IOException e) {
			
			e.printStackTrace();
		}
	
	}
}

 

package nio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
import java.util.Iterator;

/**
 *
 *Nio客户端,一个线程同时发起多个通道
 */
public class NioClient {
	String host="127.0.0.1";
	int port=9999;
	CharsetEncoder encoder=Charset.forName("GB2312").newEncoder();
	CharsetDecoder decoder=Charset.forName("GB2312").newDecoder();
	SocketChannel channel;
	Selector selector;
	ByteBuffer buffer=ByteBuffer.allocate(1024);
	
	public  void initSelector() throws IOException{
		selector=Selector.open();
	}
	
	public void initClient() throws IOException{
		 channel=SocketChannel.open();
		 channel.configureBlocking(false);
		 channel.register(selector, SelectionKey.OP_CONNECT);
		 channel.connect(new InetSocketAddress(host,port));
	}
	
    public void process() throws IOException{
         	for(;;){
         		selector.select();
         		Iterator<SelectionKey> keys=selector.selectedKeys().iterator();
         		while (keys.hasNext()) {
         			SelectionKey key=keys.next();
         			if(key.isConnectable()){
         				SocketChannel sc=(SocketChannel) key.channel();
         				if(sc.isConnectionPending()){
         					sc.finishConnect();
         				}
         				sc.write(encoder.encode(CharBuffer.wrap("你好! 服务器!")));
         				sc.register(selector, SelectionKey.OP_READ);
         			}else if(key.isReadable()){
         				SocketChannel sc=(SocketChannel) key.channel();
         				if(sc.read(buffer)>0){
         					buffer.flip();
         					System.out.println(decoder.decode(buffer).toString());
         					buffer.clear();
         				}else {
         					sc.close();
						}
         			}
				}
         	}
    }
    
	public static void main(String[] args) {
		NioClient client=new NioClient();
		try {
			client.initSelector();
			client.initClient();
			client.process();
		} catch (IOException e) {
			
			e.printStackTrace();
		}
		
	
	}
}

 

NIO有众多的实现:mina 、tomcat、jttey等。

分享到:
评论

相关推荐

    java NIO和java并发编程的书籍

    java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java...

    JavaNIO chm帮助文档

    Java NIO系列教程(一) Java NIO 概述 Java NIO系列教程(二) Channel Java NIO系列教程(三) Buffer Java NIO系列教程(四) Scatter/Gather Java NIO系列教程(五) 通道之间的数据传输 Java NIO系列教程(六)...

    Java NIO英文高清原版

    Java NIO,全称为Non-Blocking Input/Output(非阻塞输入/输出),是Java平台中用于替代标准I/O(BIO)模型的一种新机制。NIO在Java 1.4版本引入,提供了更高效的数据处理和通道通信方式,特别适用于高并发、大数据...

    java NIO.zip

    Java NIO,全称为Non-Blocking Input/Output(非阻塞输入/输出),是Java标准库提供的一种替代传统的I/O模型的新技术。自Java 1.4版本引入NIO后,它为Java开发者提供了更高效的数据传输方式,尤其是在处理大量并发...

    java nio 包读取超大数据文件

    ### Java NIO 处理超大数据文件的知识点详解 #### 一、Java NIO简介 Java NIO(New IO)是Java平台上的新输入/输出流API,它提供了与传统IO(即Java IO)不同的数据处理方式。NIO在Java 1.4版本引入,并在后续版本...

    java NIO 视频教程

    Java NIO(New IO)是一个可以替代标准Java IO API的IO API(从Java 1.4开始),Java NIO提供了与标准IO不同的IO工作方式。 Java NIO: Channels and Buffers(通道和缓冲区) 标准的IO基于字节流和字符流进行操作的,...

    Java NIO 中文 Java NIO 中文 Java NIO 中文文档

    Java NIO 深入探讨了 1.4 版的 I/O 新特性,并告诉您如何使用这些特性来极大地提升您所写的 Java 代码的执行效率。这本小册子就程序员所面临的有代表性的 I/O 问题作了详尽阐述,并讲解了 如何才能充分利用新的 I/O ...

    java NIO技巧及原理

    Java NIO(New Input/Output)是Java标准库提供的一种I/O模型,它与传统的 Blocking I/O(IO)相比,提供了更加高效的数据传输方式。在Java NIO中,"新"主要体现在非阻塞和多路复用这两个特性上,这使得NIO更适合于...

    一个java NIO的例子

    Java NIO,全称为Non-Blocking Input/Output(非阻塞输入/输出),是Java标准库提供的一种替代传统I/O模型的新技术。在传统的Java IO模型中,读写操作是阻塞的,即当调用read或write方法时,线程会等待数据准备好或...

    java NIO实例

    Java NIO,全称为Non-Blocking Input/Output(非阻塞输入/输出),是Java从1.4版本开始引入的一种新的I/O模型,它为Java应用程序提供了更高效的数据传输方式。传统的Java I/O模型(BIO)在处理大量并发连接时效率较...

    java nio入门学习,两个pdf

    Java NIO,全称为Non-Blocking Input/Output(非阻塞输入/输出),是Java标准库提供的一种替代传统I/O模型的新技术。在Java 1.4版本中引入,NIO提供了一种全新的I/O编程方式,使得Java开发者能够更高效地处理I/O操作...

    java nio 实现socket

    ### Java NIO 实现Socket通信详解 #### 一、NIO与传统IO的区别及优势 在探讨如何使用Java NIO实现Socket通信之前,我们需要先理解NIO(Non-blocking I/O,非阻塞I/O)与传统阻塞I/O之间的区别。 **传统阻塞I/O...

    Java NIO测试示例

    Java NIO,全称为Non-Blocking Input/Output(非阻塞输入/输出),是Java从1.4版本开始引入的一种新的I/O模型,它为Java应用程序提供了更高效、灵活的I/O操作方式。NIO与传统的 Blocking I/O(阻塞I/O)模式相比,...

Global site tag (gtag.js) - Google Analytics