前言
适用springboot 简单搭建了一个小环境,通过classLoader获取classpath下的文件夹中的文件,批量获取文件,也许你不知道有多少文件和文件的名称,基于这个情况下总结了一些经验教训
环境
-
resource下创建文件夹
这里创建了2个文件,a 和b , 如果我们确定知道文件名称 就好办了 通过classLoader.getResourceAsStream() 即可获取, 假设我们不知道文件名称和数量 -
编写测试类
错 误 代 码 示 范 \color{red}{错误代码示范} 错误代码示范
// 获取class 根目录 URL resource = FileJar.class.getClassLoader().getResource("my/file"); System.out.println(resource.getPath()); // 获取my/file 下的所有文件 File[] files = new File(resource.getPath()).listFiles(); if (files != null) { Arrays.stream(files).forEach(e -> System.out.println("file path = " + e.getAbsolutePath())); }
输出
/F:/workSpaces/idea/springboot-test/file-jar/target/classes/my/file file path = F:\workSpaces\idea\springboot-test\file-jar\target\classes\my\file\a.txt file path = F:\workSpaces\idea\springboot-test\file-jar\target\classes\my\file\b.txt
** 看似没问题,但是打包为jar后输出
file:/F:/workSpaces/idea/springboot-test/file-jar/target/file-jar-0.0.1-SNAPSHOT.jar!/BOOT-INF/classes!/my/file
是一个压缩文件 jar路径, file 是读取不了的**
正确方式
Enumeration<URL> resources = FileJar.class.getClassLoader().getResources("my/file");
while (resources.hasMoreElements()) {
URL url = resources.nextElement();
// 通过判断协议是不是jar文件
if (url.getProtocol().equals("jar")) {
JarURLConnection urlConnection = (JarURLConnection) url.openConnection();
JarFile jarFile = urlConnection.getJarFile();
Enumeration<JarEntry> entries = jarFile.entries(); // 返回jar中所有的文件目录
while (entries.hasMoreElements()) {
JarEntry jarEntry = entries.nextElement();
if (!jarEntry.isDirectory() && jarEntry.getName().startsWith("my/file")) {
// 是我们需要的文件类型
String name = jarEntry.getName();
System.out.println("name = " + name);
InputStream resourceAsStream = FileJar.class.getClassLoader().getResourceAsStream(name);
Properties p = new Properties();
p.load(resourceAsStream);
System.out.println(p);
}
}
} else if (url.getProtocol().equals("file")) {
// 获取class 根目录
URL resource = FileJar.class.getClassLoader().getResource("my/file");
System.out.println(resource.getPath());
// 获取my/file 下的所有文件
File[] files = new File(resource.getPath()).listFiles();
if (files != null) {
Arrays.stream(files).forEach(e -> System.out.println("file path = " + e.getAbsolutePath()));
}
}
}
通过jarFile 来获取jar包中的文件, 如果有其他jar包和你的文件夹命名相同可以添加 url条件进行判断
知识点
ClassLoader.getResource(String name);
ClassLoader.getResource(""); // 获取的是项目根目录,也就是到classes/这一层
ClassLoader.getResources(String name);
ClassLoader.getResources("my/file/a.properties"); // 加载多个jar文件中的 my/file/a.properties 文件, springboot的spring.factories 就是这么加载的
ClassLoader.getResourceAsStream(String name);