背景:
想要读取一段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.慎重使用路径的方式读取文件,意味着代码的通用性更低,有可能给自己埋下更多的坑。