• Java基础回顾 —NIO


    1. java.io包中面向流stream-oriented。NIO采用面向块的概念block-oriented。
      即NIO操作以大的数据块为单位进行,而不是一次一个字节或字符进行。这样做 性能得以提高,但是却牺牲了操作的简单性。
    2. NIO提供与平台无关的非阻塞I/O (nonblocking I/O),与面向线程的、阻塞式I/O方式相比,多道通信、非阻塞I/O即使可以是应用程序更有效的处理大量连接的情况。
    3. 缓冲区与Buffer
      基本IO操作都是直接以流的形式完成;NIO所有的操作都要使用到缓冲区处理,且所有的读写操作都是在缓冲区完成的。
      缓冲区Buffer是一个线性的、有序的数据集,只能容纳某种特定的数据类型。
    4. 缓冲区的状态
      position:表示下一个缓冲区读取或写入的操作指针,指针永远放在写入的最后一个元素之后。开始时position为0.
      limit:表示第一个不应该被读出或者写入缓冲区的位置索引,开始时limit为capacity。position<=limit
      capacity:表示缓冲区的最大容量,limit<=capacity,在分配缓冲区时被设置,一般不会被修改。
    5. 在执行 flip()方法时,一般limit设置为position,position设置为0,使得Buffer的读写指针又移到了开始的位置,表示在调用flip()之后,Buffer为输出做好准备。而当Buffer输出完数据之后,调用 clear()方法,不是 清空Buffer数据(数据任然存在),而是仅仅将position设置为0,将limit设置为capacity,再次为向Buffer
      中装入数据做准备。
    6. slice()方法会从一个缓冲区中创建一个新的子缓冲区, 子缓冲区与原缓冲区的部分数据可以共享。
    7. asReadOnlyBuffer()创建一个只读缓冲区。
    8. ByteBuffer可以创建直接缓冲区,这样Java虚拟机将尽最大努力直接对其执行本机的IO操作。即每次调用基础操作系统的一次本机IO操作前后,虚拟机都会尽量避免将缓冲区的内容复制到中间缓冲区,或者从中间缓冲区复制内容。通过 ByteBuffer.allocateDirect(int capacity);
      Buffer的put()和get()访问数据有两种方式:
      • 相对的:从Buffer当前position读取或写入数据,同时将position的值按处理元素个数增加。
      • 绝对的:根据索引向Buffer中读取或写入数据,此方式不会影响position的值。eg: buffer.get(2) - 获取第三个元素。
    9. 通道:Channel可以用来读取和写入数据,类似于输入输出流,但是 程序不会直接操作通道,所有内容都是先读到或写入缓冲区,再通过缓冲区取得或写入。
    10. 通道与传统流操作不同,传统流操作分为输入流和输出流,而 通道本身是双向操作的,既可以完成输入也可以完成输出。
    11. 内存映射:将文件映射到内存中,这样文件内的数据就可以用内存读/写指令来访问,而不需要使用InputStream或OutputStream这样的I/O操作类, 这种方式读取文件的速度是最快的。通过FileChannel的map()方法。
    12. Java访问文件的四种方法:
      • RandomAccessFile:随机读取数据,速度较慢。
      • FileInputStream:文件输入流,速度较慢。
      • 缓冲读取( eg: BufferReader):速度较快。
      • 内存映射( eg: MappedByteBuffer),速度最快。
    13. FileChannel的三种内存映射模式:
      • READ_ONLY:只读映射模式。
      • READ_WRITE:读取/写入映射模式。
      • PRIVATE:专用(写入时复制)模式。
    14. 文件锁FileLock:当一个线程将文件锁定之后,其他线程无法操作此A文件。
    15. 文件锁的两种方式: isShared = true or false
      • 共享锁:允许多个线程进行文件的读取操作。
      • 独占锁:只允许一个线程进行文件的读/写操作。
    16. 字符集Charset:负责处理编码的问题。
      • CharsetEncoder:创建编码器。
      • CharsetDecoder:创建解码器。
    17. 在原来使用的IO和Socket构建网络服务时,所有的网络服务将使用阻塞的方式进行客户端的连接, NIO则通过Selector构建一个非阻塞的网络服务。
    18. 在进行非阻塞网络开发时需要使用SelectableChannel类向Select类注册,而且在新的IO中实现网络程序需要依靠ServerSocketChannel类和ServerChannel类,这两个类都是SelectableChannel的子类,SelectorChannel提供了注册Selector的方法和阻塞模式。
    19. ServerSocketChannel在使用register()方法时需要指定一个选择器(Selector对象),以及Select域。
      tips: 服务器上所有的Channel(包括ServerSocketChannel和SocketChannel)都需要向Selector注册,而该Selector则负责监视这些Socket的IO状态,当其中任意一个或多个Channel具有可用的IO操作时,该Selector的Select()方法将会返回大于0的整数,该整数值就表示该Selector上有多少个Channel具有可用的IO操作,并提供了selectionKeys()方法来返回这些Channel的SelectionKey集合,使得服务器只需要不停的调用Selector的select()方法即可知道当前的所有Channel是否有需要处理的IO操作。如果没有Channel有需要处理的IO操作,select()方法会被阻塞。
    20. Java 7 -- NIO2:
      Path - 与平台无关的平台路径。
      • 使用WatchService来监控文件变化,监听path下文件变化,获取 "WatchService ws = FileSystems.getDefault().newWatchService()",register()方法完成注册,接下来调用WatchService的take()方法来获取被监听目录文件变化事件。
        Paths - Path工具类,包含了创建Path的两个静态工厂方法。
        Files - File工具类,包含大量静态方法操作文件,包括文件的读取、写入、复制。
      • 可以使用FileVisitor遍历文件和目录。FileVisitor代表一个文件访问器,walkFileTree(Path path, FileVisitor fileVisitor)方法会遍历path下的所有文件和子目录,遍历文件就会触发FileVisitor的相关方法。FileVisitorResult是一个枚举类,代表了访问的后续行为。
      • 访问文件属性getFileAttributeView():
        • AclFileAttributeView: 获取或修改文件权限。
        • BasicFileAttributeView: 获取或修改文件的基本属性。
        • DosFileAttributeView: 获取或修改文件的DOS属性,比如是否隐藏、是否为系统文件。
        • FileOwnerAttributeView: 获取或修改文件的所有者。
        • UserDefinedFileAttributeView: 开发者为文件设置一些自定义属性。
  • 相关阅读:
    supervisor使用小记
    linux新增定时脚本
    page_fault_in_nonpaged_area异常解决方案(已解决)
    和安卓对接老是ping不通?试试内网映射
    github文件下载加速器
    mybatis新增账号并且返回主键id
    arraylist源码解析
    MySQL安装教程
    通过get方法的方式获取配置项信息
    @Inject注解
  • 原文地址:https://www.cnblogs.com/nextStep/p/6693369.html
Copyright © 2020-2023  润新知