在一个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());
这个结果会给你一个文件列表和它们的内容。