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: 开发者为文件设置一些自定义属性。
posted @ 2017-04-11 14:19  涣涣虚心  阅读(116)  评论(0编辑  收藏  举报