JAVA NIO 学习总结

来源:互联网 发布:广东干部网络课程技巧 编辑:程序博客网 时间:2024/06/05 09:39

JAVA NIO 学习总结


最近一个开发项目中需要用到,马不停蹄的学习,总结的一点儿。如有不恰,欢迎大家给予宝贵意见及匡正:1034913380@qq.com

NIO是java4中新出的api 原生io类似Strea流一样进行数据的传输,但是又很大的区别于stream



    1.Channel(通道)好比是outputStream这样的流,作为数据传输的通道,NIO 中的Channel同传统IO中的Stream来比,IO是单向的,只能读或者写,但是Channel能读能写双向的。

    2.Buffer缓冲区,NIO中所有的数据读写都离不开Buffer,就相当于我们操作传统IO时需要的byte来临时存放数据是一样的。客户端发送请求现将数据放到Buffer中然后Channel通道把数据写进去发送,服务器接到数据先从Channel冲取出数据到Buffer中,之后再处理;所以不管读写数据都要先把数据放到Buffer中。

    3.Selector(选择器,监听Channel中的事件),用来轮询每个注册了的Channel,一旦发现有事件发生,取出事件做相应的处理。一个线程处理一个selector,通过Selector.select()方法来获取到达事件,在根据事件进行相应处理。多个客户端访问的时候不需要每个都开一个线程,直接用这样的方式监听,节省资源。但是使用NIO更多的是为了通过多线程充分使用多个CPU的处理能力和处理中的等待时间,提高处理的能力。


Channel(通道)有以下几类:

    

  • FileChannel

  • SocketChanel

  • ServerSocketChannel

  • DatagramChannel


FileChannel 可以进行文件的读写数据;

SocketChannel 可以通过TCP向网络连接两端读写数据,

ServerSocketChannel 则是基于TCP协议上的服务器端用来监听客户端来的请求,为每个请求创建一个SocketChannel用于数据的交互

DatagramChannel 是用来做UDP连接基础上的的网络连接两端进行数据的交互。


public class FileChannel {

/**

 * 测试文件的FileChannel

 * @param args

 */

public static void main(String[] args) throws Exception{

File file = new File("D:/test.txt"); 

FileOutputStream fos = new FileOutputStream(file);

java.nio.channels.FileChannel fc = fos.getChannel();

ByteBuffer bb = ByteBuffer.allocate(1024);

bb.put("FileChannel Test".getBytes());

//flip()是为新一轮的信道读写数据做好准备,将limit设为了当前position的值,再将position设为0

bb.flip();

fc.write(bb);

fc.close();

fos.close();

}

}




Buffer(缓冲区)

    ​是以连续数组实现的一个装载读写数据的容器,Channel读写数据(文件,网络数据)都要经过Buffer。

客户端发送请求数据,data是先被放在了Buffer中,随后利用Channel(通道)发送到服务器,服务器从Channel中取出数据到Buffer中最后处理。具体可以看看下面的图


Buffer通常会有用到的子类,它自身是抽象类:

  • ByteBuffer

  • IntBuffer

  • CharBuffer

  • LongBuffer

  • DoubleBuffer

  • FloatBuffer

  • ShortBuffer


一般网络读写ByteBuffer 就能满足日常开发需要。

具体Buffer其他属性(limit position)可以参看http://blog.sina.com.cn/s/blog_4bc179a80100xiy5.html


Selector(选择器)

用于监听多个注册了的Channel通道上的客户端请求数据出发的事件,这里只需要一个线程就能管理多个通道,不需要每个客户端开启一个线程。

节省大量系统资源,维护线程的成本。

要使用Selector,得向Selector注册Channel,然后调用它的select()方法。这个方法会一直阻塞到某个注册的通道有事件就绪。一旦这个方法返回,线程就可以处理这些事件。接着处理数据


好了从深夜1点写到现在4点,希望总结的一点能帮助到大家。看似很少的东西但是还是花了3个钟,哈欠  不说了洗洗睡。

0 0