读取Jar中文件使用类似getResourceAsStream等以流的方式获取即可。但是想要读取Jar中某个目录下的所有文件却不是那么容易。
第一种方式
首先要读取Jar中的目录下的文件,得先搞清楚Jar中的目录结构,例如常见的SpringBoot打包后的Jar中目录如下:
假如我们要读取的目录是BOOT-INF/classes/processes
(对应源文件目录是resources/processes
)
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| URL url = this.getClass().getClassLoader().getResource(""); String jarPath = url.toString().substring(0, url.toString().indexOf("!/") + 2); log.info("jarPath:{}", jarPath); URL jarURL = new URL(jarPath); JarURLConnection jarCon = (JarURLConnection) jarURL.openConnection(); JarFile jarFile = jarCon.getJarFile();
Enumeration<JarEntry> entries = jarFile.entries();
while (entries.hasMoreElements()) { JarEntry jarEntry = entries.nextElement(); String innerPath = jarEntry.getName(); log.info("jarEntry Name:{}", innerPath); if (innerPath.startsWith(PROCESSES) && !jarEntry.isDirectory()) { InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(innerPath); } } }
|
此方式优缺点:无第三方库依赖,用的都是JDK 相关API。但是只能在jar模式下运行,本地调试会出错。
第二种方式
如果有使用到Spring,那么不管是打成Jar运行还是本地运行,获取指定目录中的文件就很简单了。主要是利用了Spring 的ResourcePatternResolver
,详细代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| List<Resource> resourceList = new ArrayList<>();
for (String suffix : PROCESS_DEFINITION_LOCATION_SUFFIXES) { String path = PROCESS_DEFINITION_LOCATION_PREFIX + suffix; Resource[] resources = resourceLoader.getResources(path); if (resources != null && resources.length > 0) { resourceList.addAll(Arrays.asList(resources)); } }
|
此方式优缺点,依赖了Spring框架,但是对运行环境没有要求。
总结:
推荐使用第二种方式,毕竟现在基本上都会使用到Spring。