vertx.FileResolver文件解析

FileResolver Class

//文件复制解析,复制文件到cache directory 中 ,VM options : -Dvertx.disableFileCPResolving
public static final String DISABLE_CP_RESOLVING_PROP_NAME = "vertx.disableFileCPResolving";
private static final boolean ENABLE_CP_RESOLVING = !Boolean.getBoolean(DISABLE_CP_RESOLVING_PROP_NAME);

/**
  * enableCaching 文件解析器是否用缓存,默认ture, 
  * 设置两种方式:一、VertxOptions类的setFileResolverCachingEnabled方法
  * 二、设置system property,VM options "-Dvertx.disableFileCaching",对原代码无侵入性
  */
public FileResolver(Vertx vertx, boolean enableCaching) {
    this.vertx = vertx;
    this.enableCaching = enableCaching;
    //获取工作目录 -Dvertx.cwd
    String cwdOverride = System.getProperty("vertx.cwd");
    if (cwdOverride != null) {
      cwd = new File(cwdOverride).getAbsoluteFile();
    } else {
      cwd = null;
    }
    if (ENABLE_CP_RESOLVING) {
      setupCacheDir();
    }
}


/**
  *  建立cache目录
  */
private void setupCacheDir() {
  //CACHE_DIR_BASE 通过-Dvertx.cacheDirBase设置,默认当前工作目录 .vertx隐藏目录下
    String cacheDirName = CACHE_DIR_BASE + "/file-cache-" + UUID.randomUUID().toString();
    cacheDir = new File(cacheDirName);
    if (!cacheDir.mkdirs()) {
      throw new IllegalStateException("Failed to create cache dir");
    }
    // 添加 shutdown hook,kill -15 pid 触发缓存清理
    shutdownHook = new Thread(() -> {
      CountDownLatch latch = new CountDownLatch(1);
      deleteCacheDir(ar -> latch.countDown());
      try {
        latch.await(10, TimeUnit.SECONDS);
      } catch (Exception ignore) {
      }
    });
    Runtime.getRuntime().addShutdownHook(shutdownHook);
}

/**
  * 删除cache目录
  */
private void deleteCacheDir(Handler<AsyncResult<Void>> handler) {
    if (cacheDir != null && cacheDir.exists()) {
      vertx.fileSystem().deleteRecursive(cacheDir.getAbsolutePath(), true, handler);
    } else {
      handler.handle(Future.succeededFuture());
    }
}

 

解析文件

/**
 * 解析文件
 */
public File resolveFile(String fileName) {
    // 现在disk查找文件
    File file = new File(fileName);
    if (cwd != null && !file.isAbsolute()) {//是否是绝对路径
      file = new File(cwd, fileName);
    }
    // -Dvertx.disableFileCPResolving 设置
    if (!ENABLE_CP_RESOLVING) {
      return file;
    }
    
    /**
     * synchronized同步块,防止多线程对cache directory操作导致线程安全问题
     */
    synchronized (this) {
      if (!file.exists()) {
        // 首先本地文件cache 查找
        File cacheFile = new File(cacheDir, fileName);
        if (enableCaching && cacheFile.exists()) {
          return cacheFile;
        }
        // 在classpath 查找
        ClassLoader cl = getClassLoader();
        //检查是否是UNIX separator,不是将文件路径 \ 替换为 /,不同操作系统 separator 存在差异
        if (NON_UNIX_FILE_SEP) {
          fileName = fileName.replace(FILE_SEP, "/");
        }

        
        String parentFileName = file.getParent();
        if (parentFileName != null) {
        //缓存父目录中存在的所有资源
          URL directoryContents = cl.getResource(parentFileName);
          if (directoryContents != null) {
            unpackUrlResource(directoryContents, parentFileName, cl, true);
          }
        }

        URL url = cl.getResource(fileName);
        if (url != null) {
          return unpackUrlResource(url, fileName, cl, false);
        }
      }
    }
    return file;
}

/**
  * 复制目录下所有文件到cacheDir目录下
  */
private File unpackUrlResource(URL url, String fileName, ClassLoader cl, boolean isDir) {
  //获取协议
    String prot = url.getProtocol();
    switch (prot) {
      case "file":
        return unpackFromFileURL(url, fileName, cl);
      case "jar":
        return unpackFromJarURL(url, fileName, cl);
      case "bundle": // Apache Felix, Knopflerfish
      case "bundleentry": // Equinox
      case "bundleresource": // Equinox
        return unpackFromBundleURL(url, isDir);
      default:
        throw new IllegalStateException("Invalid url protocol: " + prot);
    }
}

note:有时启动不了Application,很大可能由于用户权限问题无法建立cache directory 所导致

转载于:https://www.cnblogs.com/cmfa/p/10550757.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值