在 SpringBoot 2.0.1.RELEASE 应用程序中读取文件 [英] Reading files in a SpringBoot 2.0.1.RELEASE app
问题描述
我有一个 SpringBoot 2.0.1.RELEASE mvc 应用程序.在资源文件夹中,我有一个名为/elcordelaciutat 的文件夹.
I have a SpringBoot 2.0.1.RELEASE mvc application. In the resources folder I have a folder named /elcordelaciutat.
在控制器中我有这个方法来读取文件夹内的所有文件
In the controller I have this method to read all the files inside the folder
ClassLoader classLoader = this.getClass().getClassLoader();
Path configFilePath = Paths.get(classLoader.getResource("elcordelaciutat").toURI());
List<String> cintaFileNames = Files.walk(configFilePath)
.filter(s -> s.toString().endsWith(".txt"))
.map(p -> p.subpath(8, 9).toString().toUpperCase() + " / " + p.getFileName().toString())
.sorted()
.collect(toList());
return cintaFileNames;
运行应用程序.来自 Eclipse 的工作正常,但是当我在 Windows Server 中运行该应用程序时,出现此错误:
running the app. from Eclipse is working fine, but when I run the app in a Windows Server I got this error:
java.nio.file.FileSystemNotFoundException: null
at com.sun.nio.zipfs.ZipFileSystemProvider.getFileSystem(ZipFileSystemProvider.java:171)
at com.sun.nio.zipfs.ZipFileSystemProvider.getPath(ZipFileSystemProvider.java:157)
at java.nio.file.Paths.get(Unknown Source)
at
我解压了生成的jar文件,文件夹就在那里!
I unzipped the generated jar file and the folder is there !
文件夹的结构是
elcordelaciutat/folder1/*.txt
elcordelaciutat/folder2/*.txt
elcordelaciutat/folder3/*.txt
推荐答案
我发现 ResourceLoader
和 ResourcePatternUtils
的组合是列出/读取文件的最佳方式来自 Spring Boot 应用程序中的类路径资源文件夹:
I found the combination of ResourceLoader
and ResourcePatternUtils
to be the most optimum way of listing/reading files from a classpath resource folder in a Spring Boot application:
@RestController
public class ExampleController {
private ResourceLoader resourceLoader;
@Autowired
public ExampleController(ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;
}
private List<String> getFiles() throws IOException {
Resource[] resources = ResourcePatternUtils
.getResourcePatternResolver(loader)
.getResources("classpath*:elcordelaciutat/*.txt");
return Arrays.stream(resources)
.map(p -> p.getFilename().toUpperCase())
.sorted()
.collect(toList());
}
}
更新
如果要获取所有文件,包括elcordelaciutat
子文件夹中的文件,则需要包含以下模式classpath*:elcordelaciutat/**
.这将检索子文件夹中的文件,包括子文件夹.获得所有资源后,根据 .txt
文件扩展名对其进行过滤.以下是您需要进行的更改:
Updates
If you want to fetch all the files including the files in subfolders of elcordelaciutat
, you need to include the following pattern classpath*:elcordelaciutat/**
. This would retrieve the files in the subfolders including the subfolders. Once you get all the resources, filter them based on .txt
file extension. Here are the changes you need to make:
private List<String> getFiles() throws IOException {
Resource[] resources = ResourcePatternUtils
.getResourcePatternResolver(loader)
// notice **
.getResources("classpath*:elcordelaciutat/**");
return Arrays.stream(resources)
.filter(p -> p.getFilename().endsWith(".txt"))
.map(p -> {
try {
String path = p.getURI().toString();
String partialPath = path.substring(
path.indexOf("elcordelaciutat"));
return partialPath;
} catch (IOException e) {
e.printStackTrace();
}
return "";
})
.sorted()
.collect(toList());
}
假设您有以下资源文件夹结构:
Let's say if you have the following resources folder structure:
+ resources
+ elcordelaciutat
- FileA.txt
- FileB.txt
+ a-dir
- c.txt
+ c-dir
- d.txt
+ b-dir
- b.txt
过滤后,列表将包含以下字符串:
After filtering, the list will contain the following strings:
elcordelaciutat/FileA.txt
elcordelaciutat/FileB.txt
elcordelaciutat/a-dir/c-dir/d.txt
elcordelaciutat/a-dir/c.txt
elcordelaciutat/b-dir/b.txt
当你想读取一个资源时,你应该总是使用方法getInputStream()
.
When you want to read a resource, you should always use the method getInputStream()
.
这篇关于在 SpringBoot 2.0.1.RELEASE 应用程序中读取文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!