Spring引导-列出类路径中的所有文件



在一个spring启动应用程序中,我有应用程序。属性为

的Yaml文件
files:
paths: /csvfiles/

src/main/resource中,我们有一个名为csvfiles的文件夹,其中包含我想要读取的csv文件列表。

我正在尝试搜索相同的,但没有得到任何适当的方法来实现相同。

getClass().getResourceAsStream("/files/paths")只能用于获取特定文件,而不能用于获取文件列表。

列出所有文件后,我想按顺序读取它们

在Spring中,一种解决方案是,您可以从属于类路径

的文件夹中注入资源数组。
@Value("classpath:path/*")
private Resource[] files;

假设您的代码被构建到一个可执行的jar中,那么jar中没有src/main/resources。您可以做的是列出jar文件的内容,然后根据每个条目的路径,选择路径中包含csvfiles的条目。

要查找一个类来自哪个jar,请参见此。要列出jar文件的内容,请参见:

显然,这在本地运行时不起作用,所以您需要一个替代方案。您可以使用这个找到类文件的位置,然后导航到相对于它的csvfiles目录。

这是YourClass.class.getResourceAsStream,而不是getClass(),如果你子类化的东西有可能打破。

getResource机制基本上不知道文件夹是什么,也不能给您一个列表。时期。classloader是一种抽象,它们可以被实现为读取jar文件,磁盘上的目录,也可以从网络加载,从数据库检索,或者动态生成,关键的是,根本没有请列出文件夹内容选项,所以无论你在那里找到什么(有一些库之类的)都是无法在这种情况下工作的hack。

常见的解决方案是创建一个列出资源的文本文件。现在,您不再依赖于不可用的"列表文件"操作:相反,您可以在任何类路径项上查询该文本文件的所有版本,然后只需读取列出的每个文件。当应用于类时,这被称为SPI系统(服务提供者接口)。内置到java.*本身是读取它们的能力,尽管它们是为类而不是文件设计的,所以我不确定SPI系统直接适用于这里。不过,这个原则很好。

如果您想让它自动化,作为构建的一部分,您必须自动生成该文件。我不知道怎么用弹簧开机,你可能得手工维护。

一个例子:

class CsvResource {

public CsvResource(String name) {
try (var in = CsvResource.class.getResourceAsStream("/csvfiles/" + name)) {
read(in); // you write this one.
}
}
public static List<String> getAvailableNames() {
try (var in = CsvResource.class.getResourceAsStream("/csvfiles/listing.txt")) {
Arrays.stream(
new String(in.readAllBytes, StandardCharsets.UTF_8).split("s*\ns*"))
.filter(x -> !x.isEmpty())
.filter(x -> !x.startsWith("#"))
.collect(Collectors.toList());
}
}
}

捕获IOException是公平的,特别是对于丢失的csvfiles,并重新包装成运行时异常-该文件不在运行时是开发人员或devops错误,这些应该是错误或至少RuntimeExceptions。

List<File> result = Files.walk(Paths.get("classpathname"))
.filter(Files::isRegularFile)
.map(Path::toFile)
.collect(Collectors.toList());

这个结果会给你一个文件列表和它们的内容。

最新更新