模块 java.base

类 AsynchronousFileChannel

java.lang.Object
java.nio.channels.AsynchronousFileChannel
所有已实现的接口:
Closeable , AutoCloseable , AsynchronousChannel , Channel

public abstract class AsynchronousFileChannel extends Object implements AsynchronousChannel
用于读取、写入和操作文件的异步通道。

当通过调用此类定义的 open 方法之一打开文件时,将创建一个异步文件通道。该文件包含一个可变长度的字节序列,可以读取和写入,其当前大小可以是 queried 。当写入的字节超出其当前大小时,文件的大小会增加;文件大小在 truncated 时减小。

异步文件通道没有当前位置在文件中。相反,文件位置被指定给启动异步操作的每个读写方法。 CompletionHandler 被指定为参数并被调用以使用 I/O 操作的结果。该类还定义了发起异步操作的读写方法,返回一个Future 表示操作的未决结果。 Future 可用于检查操作是否已完成、等待其完成并检索结果。

除了读写操作,该类还定义了以下操作:

  • 对文件所做的更新可能forced out 到底层存储设备,确保在系统崩溃时数据不会丢失。

  • 文件的某个区域可能locked 不被其他程序访问。

AsynchronousFileChannel 与一个线程池相关联,任务被提交到该线程池以处理 I/O 事件并分派给完成处理程序,这些处理程序使用通道上的 I/O 操作结果。在通道上启动的 I/O 操作的完成处理程序保证由线程池中的线程之一调用(这确保完成处理程序由具有预期 identity 的线程运行)。如果 I/O 操作立即完成,并且发起线程本身是线程池中的一个线程,则完成处理程序可以由发起线程直接调用。当 AsynchronousFileChannel 在没有指定线程池的情况下创建时,通道将与系统相关的默认线程池相关联,该线程池可以与其他通道共享。默认线程池由 AsynchronousChannelGroup 类定义的系统属性配置。

这种类型的通道可以安全地供多个并发线程使用。 close 方法可以随时调用,由 Channel 接口指定。这会导致通道上所有未完成的异步操作以异常 AsynchronousCloseException 完成。多个读写操作可能同时未完成。当多个读写操作未完成时,I/O 操作的顺序和调用完成处理程序的顺序是不指定的;特别是,它们不能保证按照操作启动的顺序执行。读取或写入时使用的 ByteBuffers 对于多个并发 I/O 操作的使用是不安全的。此外,在启动 I/O 操作后,应注意确保在操作完成之前不会访问缓冲区。

FileChannel 一样,此类实例提供的文件视图保证与同一程序中其他实例提供的同一文件的其他视图一致。然而,由于底层操作系统执行的缓存和网络文件系统协议引起的延迟,此类实例提供的视图可能与其他同时运行的程序看到的视图一致也可能不一致。不管这些其他程序是用什么语言编写的,也不管它们是在同一台机器上还是在其他机器上运行,都是如此。任何此类不一致的确切性质取决于系统,因此未指定。

自从:
1.7
  • 构造方法详细信息

    • AsynchronousFileChannel

      protected AsynchronousFileChannel()
      初始化此类的新实例。
  • 方法详情

    • open

      public static AsynchronousFileChannel  open(Path  file, Set <? extends OpenOption > options, ExecutorService  executor, FileAttribute <?>... attrs) throws IOException
      打开或创建用于读取和/或写入的文件,返回异步文件通道以访问该文件。

      options 参数确定文件的打开方式。 READ WRITE 选项确定是否应打开文件进行读取和/或写入。如果两个选项都不包含在数组中,则打开现有文件进行读取。

      除了 READWRITE 之外,还可能存在以下选项:

      其他选项
      Option Description
      TRUNCATE_EXISTING 打开现有文件时,文件首先被截断为 0 字节大小。当文件只为阅读而打开时,该选项将被忽略。
      CREATE_NEW 如果存在此选项,则会创建一个新文件,如果该文件已经存在,则会失败。创建文件时,检查文件是否存在以及文件不存在时的创建对于其他文件系统操作是原子的。当文件只为阅读而打开时,该选项将被忽略。
      CREATE 如果存在此选项,则打开现有文件(如果存在),否则创建新文件。创建文件时,检查文件是否存在以及文件不存在时的创建对于其他文件系统操作是原子的。如果 CREATE_NEW 选项也存在或文件打开仅供阅读,则忽略此选项。
      DELETE_ON_CLOSE 如果存在此选项,则实现会在通过 close 方法关闭时尝试 best effort 删除文件。如果未调用 close 方法,则在 Java 虚拟机终止时会尝试 best effort 删除该文件。
      SPARSE 创建新文件时,此选项是 hint 新文件将是稀疏的。不创建新文件时忽略此选项。
      SYNC 要求对文件内容或元数据的每次更新都同步写入底层存储设备。 (参见 同步 I/O 文件完整性 )。
      DSYNC 要求对文件内容的每次更新都同步写入底层存储设备。 (参见 同步 I/O 文件完整性 )。

      一个实现也可能支持额外的选项。

      executor 参数是 ExecutorService ,任务将提交给该参数以处理 I/O 事件并为在结果通道上启动的操作调度完成结果。这些任务的性质是高度特定于实现的,因此在配置 Executor 时应小心。它至少应该支持无界工作队列,并且不应在 execute 方法的调用线程上运行任务。在通道打开时关闭执行程序服务会导致未指定的行为。

      attrs 参数是文件 file-attributes 的可选数组,在创建文件时自动设置。

      通过在创建 Path 的提供者上调用 newAsynchronousFileChannel 方法来创建新通道。

      参数:
      file - 要打开或创建的文件的路径
      options - 指定文件打开方式的选项
      executor - 线程池或 null 将通道与默认线程池相关联
      attrs - 创建文件时自动设置的可选文件属性列表
      返回:
      一个新的异步文件通道
      抛出:
      IllegalArgumentException - 如果集合包含无效的选项组合
      UnsupportedOperationException - 如果 file 与不支持创建异步文件通道的提供程序关联,或者指定了不支持的打开选项,或者数组包含在创建文件时无法自动设置的属性
      FileAlreadyExistsException - 如果该名称的文件已经存在并且指定了 CREATE_NEW 选项并且正在打开文件进行写入(可选的特定异常 )
      IOException - 如果发生 I/O 错误
      SecurityException - 如果安装了安全管理器并且它拒绝实施所需的未指定权限。对于默认提供程序,如果打开文件进行读取,将调用 SecurityManager.checkRead(String) 方法来检查读取访问权限。 SecurityManager.checkWrite(String) 方法被调用来检查写访问,如果文件打开写
    • open

      public static AsynchronousFileChannel  open(Path  file, OpenOption ... options) throws IOException
      打开或创建用于读取和/或写入的文件,返回异步文件通道以访问该文件。

      此方法的调用与调用的行为完全相同

         ch.open (file, opts, null, new FileAttribute<?>[0]);
       
      其中 opts 是一个 Set 包含为此方法指定的选项。

      结果通道与默认线程池相关联,任务被提交到该线程池以处理 I/O 事件并分派给完成处理程序,这些处理程序使用在结果通道上执行的异步操作的结果。

      参数:
      file - 要打开或创建的文件的路径
      options - 指定文件打开方式的选项
      返回:
      一个新的异步文件通道
      抛出:
      IllegalArgumentException - 如果集合包含无效的选项组合
      UnsupportedOperationException - 如果 file 与不支持创建文件通道的提供程序相关联,或者指定了不支持的打开选项
      FileAlreadyExistsException - 如果该名称的文件已经存在并且指定了 CREATE_NEW 选项并且正在打开文件进行写入(可选的特定异常 )
      IOException - 如果发生 I/O 错误
      SecurityException - 如果安装了安全管理器并且它拒绝实施所需的未指定权限。对于默认提供程序,如果打开文件进行读取,将调用 SecurityManager.checkRead(String) 方法来检查读取访问权限。 SecurityManager.checkWrite(String) 方法被调用来检查写访问,如果文件打开写
    • size

      public abstract long size() throws IOException
      返回此通道文件的当前大小。
      返回:
      该通道文件的当前大小,以字节为单位
      抛出:
      ClosedChannelException - 如果此通道关闭
      IOException - 如果发生其他 I/O 错误
    • truncate

      public abstract AsynchronousFileChannel  truncate(long size) throws IOException
      将此通道的文件截断为给定大小。

      如果给定的大小小于文件的当前大小,则文件将被截断,丢弃超出文件新末尾的所有字节。如果给定的大小大于或等于文件的当前大小,则文件不会被修改。

      参数:
      size - 新大小,非负字节数
      返回:
      这个文件通道
      抛出:
      NonWritableChannelException - 如果此通道未打开进行写入
      ClosedChannelException - 如果此通道关闭
      IllegalArgumentException - 如果新尺寸为负
      IOException - 如果发生其他 I/O 错误
    • force

      public abstract void force(boolean metaData) throws IOException
      强制将对此通道文件的任何更新写入包含它的存储设备。

      如果此通道的文件驻留在本地存储设备上,则当此方法返回时,可以保证自创建此通道或自上次调用此方法以来对该文件所做的所有更改都已写入该设备。这对于确保在系统崩溃时不会丢失关键信息很有用。

      如果文件不驻留在本地设备上,则不提供此类保证。

      metaData 参数可用于限制此方法需要执行的 I/O 操作数。为该参数传递 false 表示只有对文件内容的更新需要写入存储;传递 true 表示必须写入文件内容和元数据的更新,这通常需要至少一个以上的 I/O 操作。此参数是否实际有任何影响取决于底层操作系统,因此未指定。

      调用此方法可能会导致发生 I/O 操作,即使通道仅为读取而打开也是如此。例如,某些操作系统将上次访问时间作为文件元数据的一部分进行维护,并且每当读取文件时都会更新此时间。这是否实际完成取决于系统,因此未指定。

      此方法仅保证强制通过此类中定义的方法对该通道的文件所做的更改。

      参数:
      metaData - 如果是 true 则需要此方法来强制将文件内容和元数据的更改写入存储;否则,它只需要强制写入内容更改
      抛出:
      ClosedChannelException - 如果此通道关闭
      IOException - 如果发生其他 I/O 错误
    • lock

      public abstract <A> void lock(long position, long size, boolean shared, A attachment, CompletionHandler <FileLock ,? super A> handler)
      获取此通道文件的给定区域的锁。

      此方法启动一个操作以获取此通道文件的给定区域的锁。 handler 参数是一个完成处理程序,在获取锁(或操作失败)时调用。传递给完成处理程序的结果是结果 FileLock

      positionsize 参数指定的区域不需要包含在实际的底层文件中,甚至不需要重叠。锁定区域的大小是固定的;如果锁定的区域最初包含文件的末尾并且文件超出该区域,则文件的新部分将不会被锁定覆盖。如果预期文件的大小会增加并且需要锁定整个文件,则应锁定从零开始且不小于文件的预期最大大小的区域。两个参数 lock(Object,CompletionHandler) 方法简单地锁定大小为 Long.MAX_VALUE 的区域。如果 position 为非负且 size 为零,则返回大小为 Long.MAX_VALUE - position 的锁。如果与请求区域重叠的锁已被此 Java 虚拟机持有,或者已调用此方法来锁定重叠区域并且该操作尚未完成,则此方法将抛出 OverlappingFileLockException

      某些操作系统不支持以异步方式获取文件锁的机制。因此,实现可以在后台线程中或从关联线程池中的线程执行的任务中获取文件锁。如果有许多锁定操作未完成,那么它可能会无限期地消耗 Java 虚拟机中的线程。

      有些操作系统不支持共享锁,在这种情况下请求共享锁会自动转换为请求独占锁。新获取的锁是共享锁还是独占锁可以通过调用生成的锁对象的isShared 方法来测试。

      文件锁代表整个 Java 虚拟机持有。它们不适合控制同一虚拟机中多个线程对文件的访问。

      类型参数:
      A - 附件类型
      参数:
      position - 锁定区域开始的位置;必须是非负的
      size - 锁定区域的大小;必须是非负的,和 position + size 必须是非负的。值为零表示锁定从指定起始位置到文件末尾的所有字节,无论文件随后是否被扩展或截断
      shared - true 请求共享锁,在这种情况下,此通道必须打开以供读取(可能还有写入); false 请求独占锁,在这种情况下,此通道必须打开以进行写入(可能还有读取)
      attachment - 附加到 I/O 操作的对象;可以是null
      handler - 使用结果的处理程序
      抛出:
      OverlappingFileLockException - 如果与请求区域重叠的锁已被此 Java 虚拟机持有,或者已经存在锁定重叠区域的挂起尝试
      IllegalArgumentException - 如果参数的先决条件不成立
      NonReadableChannelException - 如果 shared 为真但此通道未打开供读取
      NonWritableChannelException - 如果 shared 为 false 但此通道未打开进行写入
    • lock

      public final <A> void lock(A attachment, CompletionHandler <FileLock ,? super A> handler)
      获取此通道文件的独占锁。

      此方法启动一个操作以获取此通道文件的给定区域的锁。 handler 参数是一个完成处理程序,在获取锁(或操作失败)时调用。传递给完成处理程序的结果是结果 FileLock

      ch.lock(att,handler) 形式的方法的调用与调用的行为完全相同

         ch.lock (0L, Long.MAX_VALUE, false, att, handler)
       
      类型参数:
      A - 附件类型
      参数:
      attachment - 附加到 I/O 操作的对象;可以是null
      handler - 使用结果的处理程序
      抛出:
      OverlappingFileLockException - 如果这个 Java 虚拟机已经持有锁,或者已经有一个未决的锁定区域的尝试
      NonWritableChannelException - 如果此通道未打开进行写入
    • lock

      public abstract Future <FileLock > lock(long position, long size, boolean shared)
      获取此通道文件的给定区域的锁。

      此方法启动一个操作以获取此通道文件的给定区域的锁。该方法的行为方式与 lock(long, long, boolean, Object, CompletionHandler) 方法完全相同,只是该方法不指定完成处理程序,而是返回一个 Future 表示未决结果。 Futureget 方法在成功完成时返回 FileLock

      参数:
      position - 锁定区域开始的位置;必须是非负的
      size - 锁定区域的大小;必须是非负的,和 position + size 必须是非负的。值为零表示锁定从指定起始位置到文件末尾的所有字节,无论文件随后是否被扩展或截断
      shared - true 请求共享锁,在这种情况下,此通道必须打开以供读取(可能还有写入); false 请求独占锁,在这种情况下,此通道必须打开以进行写入(可能还有读取)
      返回:
      代表未决结果的 Future 对象
      抛出:
      OverlappingFileLockException - 如果这个 Java 虚拟机已经持有锁,或者已经有一个未决的锁定区域的尝试
      IllegalArgumentException - 如果参数的先决条件不成立
      NonReadableChannelException - 如果 shared 为真但此通道未打开供读取
      NonWritableChannelException - 如果 shared 为 false 但此通道未打开进行写入
    • lock

      public final Future <FileLock > lock()
      获取此通道文件的独占锁。

      此方法启动一个操作以获取此通道文件的独占锁。该方法返回一个 Future 表示操作的未决结果。 Futureget 方法在成功完成时返回 FileLock

      此方法的调用与调用的行为完全相同

         ch.lock (0L, Long.MAX_VALUE, false)
       
      返回:
      代表未决结果的 Future 对象
      抛出:
      OverlappingFileLockException - 如果这个 Java 虚拟机已经持有锁,或者已经有一个未决的锁定区域的尝试
      NonWritableChannelException - 如果此通道未打开进行写入
    • tryLock

      public abstract FileLock  tryLock(long position, long size, boolean shared) throws IOException
      尝试获取此通道文件的给定区域的锁。

      此方法不会阻塞。调用总是立即返回,要么在请求的区域上获得了锁,要么没有这样做。如果由于另一个程序持有重叠锁而未能获得锁,则它返回 null 。如果由于任何其他原因未能获得锁,则抛出适当的异常。如果 position 为非负且 size 为零,则返回大小为 Long.MAX_VALUE - position 的锁。

      参数:
      position - 锁定区域开始的位置;必须是非负的
      size - 锁定区域的大小;必须是非负的,和 position + size 必须是非负的。值为零表示锁定从指定起始位置到文件末尾的所有字节,无论文件随后是否被扩展或截断
      shared - true 请求共享锁,false 请求排他锁
      返回:
      表示新获取的锁的锁对象,如果由于另一个程序持有重叠锁而无法获取锁,则为 null
      抛出:
      IllegalArgumentException - 如果参数的先决条件不成立
      ClosedChannelException - 如果此通道关闭
      OverlappingFileLockException - 如果与请求区域重叠的锁已被此 Java 虚拟机持有,或者如果另一个线程已在此方法中阻塞并试图锁定同一文件的重叠区域
      NonReadableChannelException - 如果 shared 为真但此通道未打开供读取
      NonWritableChannelException - 如果 shared 为 false 但此通道未打开进行写入
      IOException - 如果发生其他 I/O 错误
      参见:
    • tryLock

      public final FileLock  tryLock() throws IOException
      尝试获取此通道文件的独占锁。

      ch.tryLock() 形式的方法的调用与调用的行为完全相同

         ch.tryLock (0L, Long.MAX_VALUE, false) 
      返回:
      表示新获取的锁的锁对象,如果由于另一个程序持有重叠锁而无法获取锁,则为 null
      抛出:
      ClosedChannelException - 如果此通道关闭
      OverlappingFileLockException - 如果与请求区域重叠的锁已被此 Java 虚拟机持有,或者如果另一个线程已在此方法中阻塞并试图锁定重叠区域
      NonWritableChannelException - 如果 shared 为 false 但此通道未打开进行写入
      IOException - 如果发生其他 I/O 错误
      参见:
    • read

      public abstract <A> void read(ByteBuffer  dst, long position, A attachment, CompletionHandler <Integer ,? super A> handler)
      从给定的文件位置开始,从该通道将字节序列读入给定的缓冲区。

      此方法启动从给定文件位置开始从该通道将字节序列读取到给定缓冲区中。读取的结果是读取的字节数,如果给定位置大于或等于尝试读取时文件的大小,则为 -1

      此方法的工作方式与 AsynchronousByteChannel.read(ByteBuffer,Object,CompletionHandler) 方法相同,只是从给定文件位置开始读取字节。如果在尝试读取时给定的文件位置大于文件的大小,则不会读取任何字节。

      类型参数:
      A - 附件类型
      参数:
      dst - 要将字节传输到的缓冲区
      position - 传输开始的文件位置;必须是非负的
      attachment - 附加到 I/O 操作的对象;可以是null
      handler - 使用结果的处理程序
      抛出:
      IllegalArgumentException - 如果位置为负数或缓冲区为只读
      NonReadableChannelException - 如果这个通道没有打开阅读
    • read

      public abstract Future <Integer > read(ByteBuffer  dst, long position)
      从给定的文件位置开始,从该通道将字节序列读入给定的缓冲区。

      此方法启动从给定文件位置开始从该通道将字节序列读取到给定缓冲区中。此方法返回一个 Future 表示操作的未决结果。 Futureget 方法返回读取的字节数,如果给定位置大于或等于尝试读取时文件的大小,则返回 -1

      此方法的工作方式与 AsynchronousByteChannel.read(ByteBuffer) 方法相同,只是从给定文件位置开始读取字节。如果在尝试读取时给定的文件位置大于文件的大小,则不会读取任何字节。

      参数:
      dst - 要将字节传输到的缓冲区
      position - 传输开始的文件位置;必须是非负的
      返回:
      代表未决结果的 Future 对象
      抛出:
      IllegalArgumentException - 如果位置为负数或缓冲区为只读
      NonReadableChannelException - 如果这个通道没有打开阅读
    • write

      public abstract <A> void write(ByteBuffer  src, long position, A attachment, CompletionHandler <Integer ,? super A> handler)
      从给定的文件位置开始,从给定的缓冲区向此通道写入一个字节序列。

      此方法的工作方式与 AsynchronousByteChannel.write(ByteBuffer,Object,CompletionHandler) 方法相同,不同之处在于字节是从给定的文件位置开始写入的。如果给定的位置大于文件的大小,在尝试写入时,文件将增长以容纳新的字节;前一个文件结尾和新写入的字节之间的任何字节的值都是未指定的。

      类型参数:
      A - 附件类型
      参数:
      src - 要从中传输字节的缓冲区
      position - 传输开始的文件位置;必须是非负的
      attachment - 附加到 I/O 操作的对象;可以是null
      handler - 使用结果的处理程序
      抛出:
      IllegalArgumentException - 如果位置为负
      NonWritableChannelException - 如果此通道未打开进行写入
    • write

      public abstract Future <Integer > write(ByteBuffer  src, long position)
      从给定的文件位置开始,从给定的缓冲区向此通道写入一个字节序列。

      此方法从给定的文件位置开始,从给定的缓冲区开始将字节序列写入此通道。该方法返回一个 Future 表示写入操作的未决结果。 Futureget 方法返回写入的字节数。

      此方法的工作方式与 AsynchronousByteChannel.write(ByteBuffer) 方法相同,不同之处在于字节是从给定的文件位置开始写入的。如果给定的位置大于文件的大小,在尝试写入时,文件将增长以容纳新的字节;前一个文件结尾和新写入的字节之间的任何字节的值都是未指定的。

      参数:
      src - 要从中传输字节的缓冲区
      position - 传输开始的文件位置;必须是非负的
      返回:
      代表未决结果的 Future 对象
      抛出:
      IllegalArgumentException - 如果位置为负
      NonWritableChannelException - 如果此通道未打开进行写入