在SpringBoot 2.0.1.RELEASE应用程序中读取文件

时间:2018-04-11 11:57:06

标签: java spring spring-mvc spring-boot java.nio.file

我有一个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 Server中运行应用程序时出现了这个错误:

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

3 个答案:

答案 0 :(得分:9)

从Eclipse启动项目时,生成的类文件和资源实际上只是硬盘驱动器上的文件和文件夹。这就是它使用File类迭代这些文件的原因。

构建jar时,所有内容实际上都是ziped并存储在一个存档中。您无法再访问文件系统级工具,因此您的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")) {
        // ...
   }
}

答案 1 :(得分:3)

我发现ResourcePatternUtils@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()); } } 的组合是在Spring Boot应用程序中列出/读取类路径资源文件夹中文件的最佳方式:

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()

注意

当您想要阅读资源时,应始终使用方法Rank, Sales Dollars 1, $700 2, $200 3, $100

答案 2 :(得分:2)

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());