Module java.base

Class AsynchronousFileChannel

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

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

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

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

除了读取和写入操作,此类还定义了以下操作:

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

  • 文件的某个区域可能会被锁定,以防其他程序访问。

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

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

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

自Java版本:
1.7
  • Constructor Details

    • AsynchronousFileChannel

      protected AsynchronousFileChannel()
      初始化此类的新实例。
  • Method Details

    • open

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

      options参数确定文件的打开方式。 READWRITE 选项确定文件是否应该以读取和/或写入方式打开。如果数组中不包含任何选项,则打开现有文件以进行读取。

      除了 READWRITE,还可以包含以下选项:

      附加选项
      选项 描述
      TRUNCATE_EXISTING 打开现有文件时,首先将文件截断为0字节。当仅以读取方式打开文件时,此选项将被忽略。
      CREATE_NEW 如果存在此选项,则创建新文件,如果文件已经存在则操作失败。创建文件时,对文件的存在性检查和文件的创建(如果文件不存在)是原子性的,与其他文件系统操作一致。当仅以读取方式打开文件时,此选项将被忽略。
      CREATE 如果存在此选项,则如果存在文件则打开现有文件,否则创建新文件。创建文件时,对文件的存在性检查和文件的创建(如果文件不存在)是原子性的,与其他文件系统操作一致。如果同时存在 CREATE_NEW 选项或仅以读取方式打开文件,则此选项将被忽略。
      DELETE_ON_CLOSE 如果存在此选项,则在通过 close 方法关闭文件时,实现将尽力删除文件。如果未调用 close 方法,则在 Java 虚拟机终止时将尽力删除文件。
      SPARSE 创建新文件时,此选项是新文件将是稀疏的一个提示。如果不创建新文件,则此选项将被忽略。
      SYNC 要求将对文件内容或元数据的每次更新同步写入底层存储设备。(参见 同步 I/O 文件完整性)。
      DSYNC 要求将文件内容的每次更新同步写入底层存储设备。(参见 同步 I/O 文件完整性)。

      实现还可以支持其他选项。

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

      attrs参数是一个可选的文件属性数组,用于在创建文件时原子地设置。

      通过在创建 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 为true,但此通道未打开以进行读取
      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)方法完全相同,只是该方法不是指定完成处理程序,而是返回表示挂起结果的FutureFutureget方法在成功完成时返回FileLock

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

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

      此方法启动一个操作,以获取此通道文件的独占锁。该方法返回一个表示操作挂起结果的FutureFutureget方法在成功完成时返回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为true但此通道未打开以进行读取
      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)
      从给定缓冲区的给定文件位置开始,将一系列字节读入此通道。

      此方法启动从此通道的给定文件位置开始将一系列字节读入给定缓冲区的操作。此方法返回一个表示操作挂起结果的FutureFutureget方法返回读取的字节数,如果给定位置大于或等于尝试读取时文件的大小,则为-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)
      从给定缓冲区向此通道写入一系列字节,从给定文件位置开始。

      此方法启动从给定缓冲区向此通道写入一系列字节的操作,从给定文件位置开始。该方法返回一个表示写入操作挂起结果的FutureFutureget方法返回写入的字节数。

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

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