在 SpringBoot 2.0.1.RELEASE 应用程序中读取文件
Reading files in a SpringBoot 2.0.1.RELEASE app
我有一个 SpringBoot 2.0.1.RELEASE mvc 应用程序。
在资源文件夹中,我有一个名为 /elcordelaciutat 的文件夹。
在控制器中我有这个方法来读取文件夹中的所有文件
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 服务器中的应用程序时,我收到此错误:
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 文件,文件夹就在那里!
文件夹的结构是
elcordelaciutat/folder1/*.txt
elcordelaciutat/folder2/*.txt
elcordelaciutat/folder3/*.txt
当您从 Eclipse 启动项目时,生成的 class 文件和资源实际上只是硬盘驱动器上的文件和文件夹。这就是为什么它可以使用 File
class 遍历这些文件的原因。
当您构建 jar
时,所有内容实际上都被压缩并存储在一个存档中。您无法再使用文件系统级工具访问 is,因此您的 FileNotFound
异常。
使用 JarURL 尝试这样的操作:
JarURLConnection connection = (JarURLConnection) url.openConnection();
JarFile file = connection.getJarFile();
Enumeration<JarEntry> entries = file.entries();
while (entries.hasMoreElements()) {
JarEntry e = entries.nextElement();
if (e.getName(). endsWith("txt")) {
// ...
}
}
我发现 ResourceLoader
和 ResourcePatternUtils
的组合是从 Spring 引导应用程序的类路径资源文件夹中获取 listing/reading 文件的最佳方式:
@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
文件扩展名过滤它们。以下是您需要进行的更改:
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());
}
假设您具有以下资源文件夹结构:
+ resources
+ elcordelaciutat
- FileA.txt
- FileB.txt
+ a-dir
- c.txt
+ c-dir
- d.txt
+ b-dir
- b.txt
过滤后,列表将包含以下字符串:
elcordelaciutat/FileA.txt
elcordelaciutat/FileB.txt
elcordelaciutat/a-dir/c-dir/d.txt
elcordelaciutat/a-dir/c.txt
elcordelaciutat/b-dir/b.txt
备注
当你想阅读资源时,你应该总是使用方法getInputStream()
。
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.util.StreamUtils;
...
private static final String CURRENT_FILE = "file.txt";
public Resource getCurrentResource() {
return new ClassPathResource(CURRENT_FILE);
}
稍后在客户端代码或某些其他模块代码中,您甚至可以获取其字节:
...
Resource resource = getCurrentResource();
byte[] data = StreamUtils.copyToByteArray(resource.getInputStream());
我有一个 SpringBoot 2.0.1.RELEASE mvc 应用程序。 在资源文件夹中,我有一个名为 /elcordelaciutat 的文件夹。
在控制器中我有这个方法来读取文件夹中的所有文件
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 服务器中的应用程序时,我收到此错误:
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 文件,文件夹就在那里!
文件夹的结构是
elcordelaciutat/folder1/*.txt
elcordelaciutat/folder2/*.txt
elcordelaciutat/folder3/*.txt
当您从 Eclipse 启动项目时,生成的 class 文件和资源实际上只是硬盘驱动器上的文件和文件夹。这就是为什么它可以使用 File
class 遍历这些文件的原因。
当您构建 jar
时,所有内容实际上都被压缩并存储在一个存档中。您无法再使用文件系统级工具访问 is,因此您的 FileNotFound
异常。
使用 JarURL 尝试这样的操作:
JarURLConnection connection = (JarURLConnection) url.openConnection();
JarFile file = connection.getJarFile();
Enumeration<JarEntry> entries = file.entries();
while (entries.hasMoreElements()) {
JarEntry e = entries.nextElement();
if (e.getName(). endsWith("txt")) {
// ...
}
}
我发现 ResourceLoader
和 ResourcePatternUtils
的组合是从 Spring 引导应用程序的类路径资源文件夹中获取 listing/reading 文件的最佳方式:
@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
文件扩展名过滤它们。以下是您需要进行的更改:
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());
}
假设您具有以下资源文件夹结构:
+ resources
+ elcordelaciutat
- FileA.txt
- FileB.txt
+ a-dir
- c.txt
+ c-dir
- d.txt
+ b-dir
- b.txt
过滤后,列表将包含以下字符串:
elcordelaciutat/FileA.txt
elcordelaciutat/FileB.txt
elcordelaciutat/a-dir/c-dir/d.txt
elcordelaciutat/a-dir/c.txt
elcordelaciutat/b-dir/b.txt
备注
当你想阅读资源时,你应该总是使用方法getInputStream()
。
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.util.StreamUtils;
...
private static final String CURRENT_FILE = "file.txt";
public Resource getCurrentResource() {
return new ClassPathResource(CURRENT_FILE);
}
稍后在客户端代码或某些其他模块代码中,您甚至可以获取其字节:
...
Resource resource = getCurrentResource();
byte[] data = StreamUtils.copyToByteArray(resource.getInputStream());