Class FileSystemUtil

java.lang.Object
net.fabricmc.loom.util.FileSystemUtil

public final class FileSystemUtil extends Object
  • Method Details

    • getReadOnlyJarFileSystem

      public static FileSystemUtil.Delegate getReadOnlyJarFileSystem(Path path) throws IOException
      打开只读 jar 文件系统,走 JDK 的 newFileSystem(Path, Map) 重载.

      与 getJarFileSystem(Path, boolean) 的差别:该重载返回独立的文件系统实例, 不进入 JDK 进程级的 ZipFileSystemProvider.filesystems 登记簿,因此既不产生 FileSystemAlreadyExistsException,也不与 tiny-remapper 的全局锁 FileSystemReference.openFsMap 发生交互。多个线程可同时打开同一 jar.

      调用方须保证只读取、不写入:独立实例各自持有文件锁,对同一 jar 并发写入会失败 (AccessDeniedException)。需要写入时请用 getJarFileSystem(Path, boolean), 它经由 tiny-remapper 引用计数共享同一文件系统.

      文件不存在时抛 NoSuchFileException,与原有实现一致.

      Throws:
      IOException
    • getJarFileSystem

      public static FileSystemUtil.Delegate getJarFileSystem(File file, boolean create) throws IOException
      Throws:
      IOException
    • getJarFileSystem

      public static FileSystemUtil.Delegate getJarFileSystem(Path path, boolean create) throws IOException
      Throws:
      IOException
    • getJarFileSystem

      public static FileSystemUtil.Delegate getJarFileSystem(Path path) throws IOException
      Throws:
      IOException
    • getJarFileSystem

      public static FileSystemUtil.Delegate getJarFileSystem(URI uri, boolean create) throws IOException
      Throws:
      IOException
    • findClosedRegistryEntry

      public static @Nullable FileSystem findClosedRegistryEntry(Path path)
      探测某路径是否已被 JDK 进程级 zipfs 登记簿毒化.

      JDK-8291712:ZipFileSystem.close() 在文件已不在盘上时先抛 IOException, 来不及把实例从 ZipFileSystemProvider.filesystems 里摘掉,登记簿于是永久留下一个 「已关闭」的实例。此后凡是走 URI 路线打开同一路径的代码(tiny-remapper 的 FileSystemReference.openJar 就先查登记簿)都会拿到这个死实例, 并在第一次访问时抛出 ClosedFileSystemException。

      登记簿的 Key 含文件的真实路径,因而文件缺失期间查不到该条目、文件一重建就又查得到—— 本方法因此必须在文件存在时调用才有意义。只读诊断,不修改任何状态.

      Parameters:
      path - 待探测的 jar 路径
      Returns:
      登记簿中该路径对应的「已关闭」实例;健康(未登记或仍打开)时返回 null
    • findOpenRegistryEntry

      public static @Nullable FileSystem findOpenRegistryEntry(Path path)
      探测某路径在 JDK 进程级 zipfs 登记簿里是否有一个「仍打开」的共享实例.

      与 findClosedRegistryEntry(Path) 对称:后者找死实例(毒化),本方法找活实例。 活实例存在的含义是「此刻有持有者正拿着这个 jar 的共享实例」——登记簿的 Key 是文件的真实路径, 因此读取方按 URI 路线打开(tiny-remapper 的 FileSystemReference.openJar)时, 条目就已经在这里出现了。只读探测,不修改任何状态.

      Parameters:
      path - 待探测的 jar 路径
      Returns:
      登记簿中该路径对应的仍在打开的实例;未登记或条目已关闭时返回 null