博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
NIO学习一、NIO简介
阅读量:5811 次
发布时间:2019-06-18

本文共 2344 字,大约阅读时间需要 7 分钟。

最近在学习NIO,根据学习总结了一下,如果有不对的地方,请大佬指出。

一、NIO的简介

NIO,就是new io,从jdk  1.4开始引入的新的api,它跟IO的作用相同。它与传统的IO相比,有如下特性:1)NIO是面向缓冲区的,IO是面向流的。2)IO是阻塞的操作,如果一个io的read或者write没有得到数据的时候,会一直等待,当前线程不能做其他的事情。而NIO提供了非阻塞方式,它可以在没有数据到来之前,先做其他的事情,数据到来之后进行处理。3)NIO提供了选择器selector,通过它允许一个线程监视多个通道,避免了申请多个线程浪费资源以及线程间的频繁切换,以此提高了资源的利用率。

二、Java NIO核心部分:

Channel、Buffer、Selector Channel表示通道,通道的一端连接Buffer,另一端连接需要被操作的资源(假设资源是文件文件)。它 相当于一根管子,buffer中的数据可以通过管子写入被操作的资源当中,也可以将资源通过管子写入到buffer中去。      常用的Channel有:           FileChannel           DatagramChannel           SocketChannel           ServerSocketChannel       其中FileChannel是阻塞的,其他的可以设置成非阻塞的。 Buffer:表示缓冲区,本质是一个可以读写的内存空间,channel中的数据从资源流向buffer或者从buffer 流向资源,缓冲区有四个重要的字段,读取写入缓冲区的时候,都是操作这几个字段实现的:            capacity:内存块可以读入的大小。            position:当前指向的位置,每读取一个字节后,它都会向后移动一个位置 当前position位置            mark:标定的一个特定的位置,标定好后可以使用reset方法回到这个位置。         nio中,资源的读写操作都是通过buffer实现的。       常用的Buffer有:            ByteBuffer            MappedByteBuffer            CharBuffer            DoubleBuffer            FloatBuffer            IntBuffer            LongBuffer            ShortBuffer   Selector:nio中最重要的一部分,一个selector可以管理多个channel,当selecot管理的channel没有准备好的时候,selecot就阻塞,当有channel准备好需要操作的时候,selecot就被唤醒。传统的IO方式下,如果有多个请求到来,一般会开辟多个线程来处理这些请求,如果请求的资源没有准备好,那么线程就会处于阻塞状态,极大的浪费了资源。而NIO采用多路复用的技术,当有请求到来的时候,先注册到selector中,当注册到selector中感兴趣的请求资源准备好后,才会进行处理,(注意:注册的channel必须是同步非阻塞的)避免了传统IO中开辟的多个线程阻塞占用资源的问题。当你的每个通道的数据传输量比较低的时候,使用它会非常合适。   ps:Selector中底层设计中涉及IO多路复用,同步非阻塞知识,不懂的话先瞅瞅它们。

三、使用NIO操作的基本例子

@Test    public void test1() throws IOException {        //获取可以读写的一个文件        RandomAccessFile randomAccessFile=new RandomAccessFile("C:\\Users\\e550c\\Desktop\\日结.txt","rw");        //1、获取通道        FileChannel channel=randomAccessFile.getChannel();       //2、将通道中数据送往缓冲区        ByteBuffer byteBuffer=ByteBuffer.allocate(48);        //3、将channel中数据数据读入byteBuffer        int length=channel.read(byteBuffer);//获取缓冲区长度        while(length!=-1){            byteBuffer.flip();//4、读完数据后,调用它可以将position设置为0,limit设置为当前读取到的位置                            //以从而可以读取在这个区间中的数据            while(byteBuffer.hasRemaining()){
//当读取的buffer中有数据的时候,它会返回true System.out.println((char)byteBuffer.get());//输出 } byteBuffer.clear();//清空缓冲区 } randomAccessFile.close(); }

转载于:https://www.cnblogs.com/GregZQ/p/8365265.html

你可能感兴趣的文章
leetcode45. Jump Game II
查看>>
JS事件总结--试验过的一些小经验
查看>>
思路清奇:通过 JavaScript 获取移动设备的型号
查看>>
我眼中的前端世界
查看>>
Typescript性能调研
查看>>
leetcode21 Merge Two Sorted Lists 将两个有序链表组合成一个新的有序链表
查看>>
LeetCode - 496 Next Greater Element I
查看>>
[译]使用Haskell创业4年的感受
查看>>
文章分享(持续更新)
查看>>
包含Tomcat 9的JBoss Web Server 5已发布
查看>>
Rider EAP17带来了许多改进但缺乏.NET Core调试功能
查看>>
第四届中国汽车产业信息化技术创新峰会将于6月在沪召开
查看>>
linux清除文件内容
查看>>
区块链技术综述
查看>>
翻译 | 3种方式提升云可扩展性
查看>>
中天微致力丰富生态建设,加速客户芯片产品开发
查看>>
区块链可以减少社会不平等吗?
查看>>
飞在空中的仓库再配合无人机送货,沃尔玛新专利厉害了
查看>>
MySQL查看数据库、表的占用空间大小以及某个库中所有表的引擎类型
查看>>
WindowManager.LayoutParams 详解
查看>>