• 12、NIO、AIO、BIO一


    1、NIO概述

      什么是NIO:NIO是New I/O的简称,与旧式的基于流的I/O方式相对,从名字看,他表示新的一套JAVA I/O标准。它是在java1.4中被纳入到JDK中的,并具有以下特性:

      -NIO是基于块(BLOCK)的,它以块为基本单位处理数据(硬盘上存储的单位也是按Block来存储,这样性能上比基于流的方式要好一些)

      -为所有的原始类型提供了(Buffer)缓存支持

      -增加了通道(Channel)对象,作为新的原始I/O抽象

      -支持锁(我们在平时使用使用时经常能看到会出现一些.lock文件,这说明有线程正在使用这把锁,当线程释放锁时,会把这个文件删除掉,这样其他线程才能继续拿到这把锁) 和内存映射文件的文件访问接口

      -提供了基于Selector的异步网络I/O所有的从通道中的读写操作,都要经过Buffer,而通道就是IO

    的抽象,通道的另一端就是操纵的文件。 

    2、同步、异步、阻塞、非阻塞

      同步:使用同步IO时,java自己处理IO读写

      异步:使用异步IO时,java将IO读写委托给os处理,需要将数据缓冲区地址和大小传给os,os需要支持异步IO操作API。(编程麻烦,但是可以让java省力)

      阻塞:使用阻塞IO时,java调用会一直阻塞到读写完成才返回。

      非阻塞:使用非阻塞IO时,如果不能读写JAVA调用会马上返回,当IO时间分发器会通知可读写时再继续进行读写,不断循环只掉读写完成。

      异步IO:是指用户程序发起IO请求后,不等待数据,同时操作系统内核负责I/O操作把数据从内核拷贝到用户程序的缓冲区后通知应用程序。数据拷贝是由操作系统内核完成,用户程序从一开始就没有等待数据,发起请求后不参与任何IO操作等内核通知完成。

      同步IO:就是非异步IO的情况,也就是用户程序要参与把数据拷贝到程序缓冲区(例如java的inputStream读字节流过程)

      同步IO里的非阻塞:是指用户程序发起IO操作请求后不等待数据,而是调用会立即返回一个标志信息告知条件不满足,数据未准备好,从而程序会主动轮询查看io操作条件时候满足,如果满足,则用户程序亲自参与拷贝数据动作。

    3、AIO BIO NIO

      java BIO:Blocking IO 同步并阻塞,服务器实现模式为一个链接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个链接不做任何事情会造成不必要的线程开销,当然可以通过线程池机制改善。

      BIO方式适用于链接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中,JDK1.4以前的唯一选择,但程序直观简单易理解

      NIO:Non Blocking IO或者 New IO 同步非阻塞,服务器实现模式 为一个请求一个线程,即客户端发送的链接请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求时才启动一个线程进行处理。

      NIO方式适用于链接数目多且链接比较短(轻操作)的架构,比如聊天服务器,并发局限于应用中,编程比较复杂。

      AIO(NIO.2):Asynchronous IO或者 NIO2异步非阻塞,服务器实现模式为一个有效请求一个线程,客户端的I/O请求都是由OS先完成了再通知服务器应用去启动线程进行处理。

      AIO方式使用于连接数目多且链接比较长(重操作)的架构,比如相册服务器充分调用os参与并发操作,编程比较复杂。

    4、NIO2

      API包名为java.nio

      1、完全取代了JAVA.io.File与文件系统的交互

      2、它提供了新的异步处理类,让你无需手动配置线程池和其他底层并发控制,便可在后台线程中执行文件和网络I/O操作。

      3、它引入了新的NETWORK-CHANNEL构造方式,简化了套接字socket与通道的编码工作

     

    5、传统IO操作问题:

      a、没有数据缓冲区或通道,开发人员编程处理很多底层细节

      b、I/O操作会被阻塞,扩展能力受限。

      c、所支持的字符集编码有限

      d、不支持正则表达式,数据处理困难

    6、Path类

      Path:类中的方法可以用来获取路径信息,访问路径中的各元素,将路径转换为其他形式,或提取路径中的一个部分。

      Paths:工具类,提供返回一个路径的辅助方法,比如get方法。

      FileSystem:与文件系统交互的类。

      FileSystem:工具类,提供各种方法,比如返回默认文件系统的FileSystems.getDefault()。

    .代表当前目录   ..代表父目录

      normalize方法去掉Path中冗余信息

    Path path= Paths.get("D://HSA");和
    Path path1= FileSystems.getDefault().getPath("D://HSA");效果相同,都是提取当前路径

      Path类和FileSystem类下方法的用法:

    package com.zxc.L;
    
    import java.io.File;
    import java.io.IOException;
    import java.nio.file.FileSystem;
    import java.nio.file.FileSystems;
    import java.nio.file.Path;
    import java.nio.file.Paths;
    
    /**
     * Created by Administrator on 2018/2/6 0006.
     */
    public class A1 {
        public static void main(String[] args) {
            Path path= Paths.get("D://HSA");
            System.out.println(path);
            Path path1= FileSystems.getDefault().getPath("D://HSA");
            System.out.println(path1);
            System.out.println("文件名称["+path.getFileName()+"]");
            System.out.println("获取名称元素的数量"+path.getNameCount());
            System.out.println("父路径:"+path.getParent());
            System.out.println("父路径:"+path.getRoot());
           // System.out.println(path.subpath(2,3));//得到第二个元素路径
            Path normalizedPath=Paths.get("D://HSA").normalize();
            System.out.println( normalizedPath);//去掉了冗余符号/,留下了有用的文件名称
            //toRealPath():融合了toAbsolutePath()和normalize()两个方法的功能
            try {
                Path realPath=Paths.get("D://HSA").toRealPath();
                System.out.println( realPath);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            //resolve:将两个路径合并成一个新的路径
    
            Path prefix=Paths.get("/uat/");
            Path completePath=prefix.resolve("conf/application.properties");
            System.out.println(prefix.resolve(completePath));
    
        }
    }

     七、NIO2中文件系统操作

      文件系统的操作主要是Files类提供。如下两个类:

      Files:轻松赋值、移动、删除或处理文件的工具类

      WatchService:用来监视文件或目录的核心类,不管他们有没有变化。

      1、创建删除文件:createFile和delFile方法

      2、文件的复制和移动:copyFile和moveFile方法

      3、设置文件读写属性和获得属性:setAttr和getAttr方法

    package com.weikun.A;
    
    import java.io.IOException;
    import java.nio.file.CopyOption;
    import java.nio.file.Files;
    import java.nio.file.Path;
    import java.nio.file.Paths;
    import java.nio.file.attribute.DosFileAttributeView;
    import java.nio.file.attribute.DosFileAttributes;
    import java.nio.file.attribute.PosixFileAttributes;
    import java.nio.file.attribute.PosixFilePermission;
    import java.nio.file.attribute.PosixFilePermissions;
    import java.util.Set;
    import static java.nio.file.StandardCopyOption.COPY_ATTRIBUTES;  
    import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;  
    import static java.nio.file.StandardCopyOption.ATOMIC_MOVE;
    public class C {
        public static void moveFile(){
            try {
                Path source=Paths.get("c://2.sql");
                Path target=Paths.get("c://1/3.sql");//目录需要自己定义
                Files.move(source, target,REPLACE_EXISTING,ATOMIC_MOVE);//其中REPLACE_EXISTING,有文件存在可以替换
            } catch (Exception e) {
                // TODO: handle exception
                e.printStackTrace();
            }
        }
        public static void copyFile(){
            try {
                Path source=Paths.get("c://22.sql");
                Path target=Paths.get("c://1/1.sql");//目录需要自己定义
                Files.copy(source, target,REPLACE_EXISTING,COPY_ATTRIBUTES);//其中REPLACE_EXISTING,有文件存在可以替换
            } catch (Exception e) {
                // TODO: handle exception
                e.printStackTrace();
            }
        }
        //删除文件
        public static void delFile(){
            Path target=Paths.get("c://11.sql");
            try {
                Files.delete(target);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }//创建文件或目录
        }
        //创建文件
        public static void createFile(){
            Path target=Paths.get("c://1.sql");
            try {
                Files.createFile(target);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }//创建文件或目录
        }
        //设置已经存在文件的属性,DOS
        public static void setAttr(){//dos
            Path target=Paths.get("c://1.sql");
    
            //Path file=Files.createFile(target);//创建文件或目录
            //设置文件系统属性,适用于DOS版本
            DosFileAttributeView view = Files.getFileAttributeView(target, DosFileAttributeView.class);  
            try {
                view.setReadOnly(true);//有很多set方法,分别对应其文件各个属性
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        //读取文件属性
        public static void getAttr(){
            Path path = Paths.get("c://1.sql");  
            DosFileAttributeView view = Files.getFileAttributeView(path, DosFileAttributeView.class);  
    
            if (view != null) {  
                DosFileAttributes attrs=null;
                try {
                    attrs = view.readAttributes();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }  
                System.out.println(attrs.isReadOnly());  
            }  
        }
        public static void setAttr1(){//适用于Posix文件系统:linux unix
            try {
    
                Path path =  Paths.get("c://1.sql");
                System.out.println("最后修改时间:" +Files.getLastModifiedTime(path));
                // 第一步得到所有文件属性,放到一个PosixFileAttributes实例中
                PosixFileAttributes attrs = Files.readAttributes(path, PosixFileAttributes.class);//这里报错了
                // 第二步读取访问许可
                Set<PosixFilePermission> permissions = attrs.permissions();
                // 第三步取消默认许可
                permissions.clear();
                // 第四步定义自己的许可,使用permissions.add()方法
                permissions.add(PosixFilePermission.OWNER_WRITE);// 所有者写权限
                permissions.add(PosixFilePermission.OWNER_READ);// 所有者读权限
                permissions.add(PosixFilePermission.GROUP_READ);// 组用户读权限
                permissions.add(PosixFilePermission.OTHERS_READ);// 其他用户读权限
                Files.setPosixFilePermissions(path, permissions);// 设置新的权限;
    
    
    
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
    
        }
        public static void main(String[] args) {
            copyFile();
            
        }
    }
  • 相关阅读:
    JS判断鼠标从什么方向进入一个容器
    jQuery最核心的基础设施之一——数据缓存模块进化史
    判定模块加载时是否存在循环依赖
    mass Framework fx模块 v4
    一个简单的加载系统
    MVC历史演化
    Mozilla Firefox 17 正式发布
    javascript 堆栈与列队
    被迫才是进步的原动力(转)
    jquery1.83 之前所有与异步列队相关的模块的演变回顾
  • 原文地址:https://www.cnblogs.com/television/p/8421400.html
Copyright © 2020-2023  润新知