背景:

想要读取一段js程序,js是加密解密用途,使用的是ScriptEngineManager来获取ScriptEngine,在本地开发测试,完全ok(windows下);

上测试环境后,报错/opt/jar_code/xxx/xxxx.jar!/BOOT-INF/classes!/resources/xxxxx.js (No such file or directory)

上述目录出现"!" 比较奇怪。另外,用winrar打开jar包文件,找到相应的resource目录下,js文件是存在的,路径也没有发现问题。

一段代码:

    ClassLoader loader = XXXUtil.class.getClassLoader();
    String jsFileName = loader.getResource("") + "/resources/" + fileName;
    logger.info("文件路径为"+jsFileName);

解决方案:

不读文件路径,直接读文件流

        input = XXXUtil.class.getClassLoader()
                .getResourceAsStream("resources" + File.separator + fileName);
        reader = new InputStreamReader(input, Constant.UTF_8);

初看两种方式,应该是一致的。

其实则不同:

1.使用文件路径,要求该路径下的文件在文件系统上是可以访问的。因为jar文件需要解压才能访问,直接访问不了。

2.使用流,直接读文件,则不存在上述要求。

3.以此类推,想要读取压缩文件(zip,gzip,rar,tar,tar.gz,bzip,bzip2,rar等)中的配置文件,走路径的方式是行不通的,必须走流读取的形式。

4.可以想到,使用流读取文件的优势,可以适应在不同的场合而不用改造代码,代码的通用性更高,掉到坑里的机会更少。

5.慎重使用路径的方式读取文件,意味着代码的通用性更低,有可能给自己埋下更多的坑。