从Spring Boot中的resources文件夹中读取文件

g3b*_*blv 45 java spring spring-boot json-schema-validator

我正在使用Spring Boot和json-schema-validator.我正在尝试读取jsonschema.json从该resources文件夹调用的文件.我尝试了几种不同的方法,但我无法让它发挥作用.这是我的代码.

ClassLoader classLoader = getClass().getClassLoader();
File file = new File(classLoader.getResource("jsonschema.json").getFile());
JsonNode mySchema = JsonLoader.fromFile(file);
Run Code Online (Sandbox Code Playgroud)

这是文件的位置.

在此输入图像描述

在这里,我可以在文件classes夹中看到该文件.

在此输入图像描述

但是当我运行代码时,我得到以下错误.

jsonSchemaValidator error: java.io.FileNotFoundException: /home/user/Dev/Java/Java%20Programs/SystemRoutines/target/classes/jsonschema.json (No such file or directory)
Run Code Online (Sandbox Code Playgroud)

我在代码中做错了什么?

Joh*_*ohn 62

花了很多时间试图解决这个问题后,终于找到了一个有效的解决方案.该解决方案使用了Spring的ResourceUtils.也适用于json文件.

感谢Lokesh Gupta精心编写的页面:博客

在此输入图像描述

package utils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.ResourceUtils;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import java.io.File;


public class Utils {

    private static final Logger LOGGER = LoggerFactory.getLogger(Utils.class.getName());

    public static Properties fetchProperties(){
        Properties properties = new Properties();
        try {
            File file = ResourceUtils.getFile("classpath:application.properties");
            InputStream in = new FileInputStream(file);
            properties.load(in);
        } catch (IOException e) {
            LOGGER.error(e.getMessage());
        }
        return properties;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 这只有在您尝试从IDE运行应用程序时才有效,但是当您运行jar时,它将无法找到该文件. (19认同)
  • 同意Hassan,如果从jar运行应用程序,则应改用`new ClassPathResource(“ filename”)。getInputStream()`。[详细信息](https://www.baeldung.com/spring-classpath-file-access) (3认同)
  • @Athar 很高兴我能提供帮助。 (2认同)
  • 同意哈桑。需要注意的是,ResourceUtils Javadoc 明确指出该类主要供内部使用。也检查 /sf/ask/1810859991/#25873705 (2认同)

Tah*_*lik 32

2021年最好的方法


读取文件的最简单方法是:

    Resource resource = new ClassPathResource("jsonSchema.json");
    FileInputStream file = new FileInputStream(resource.getFile());
Run Code Online (Sandbox Code Playgroud)

  • 这在可执行 jar 中不起作用。相反,我们可以使用“InputStream inputStream = resource.getInputStream();” (23认同)

Emm*_*osu 20

花了太多时间回到这个页面,所以就把这个留在这里:

File file = new ClassPathResource("data/data.json").getFile();
Run Code Online (Sandbox Code Playgroud)

  • 在 IDE 中运行良好,但在 JAR 文件中运行不佳。 (5认同)

pov*_*nko 19

非常简短的回答:您正在寻找特定类加载器范围内的属性而不是目标类.这应该工作:

File file = new File(getClass().getResource("jsonschema.json").getFile());
JsonNode mySchema = JsonLoader.fromFile(file);
Run Code Online (Sandbox Code Playgroud)

另外,看到这个:

PS如果项目已在一台机器上编译,之后已在另一台机器上启动或您在Docker中运行您的应用程序,则可能存在问题.在这种情况下,资源文件夹的路径可能无效.在这种情况下,最好在运行时确定资源的路径:

ClassPathResource res = new ClassPathResource("jsonschema.json");    
File file = new File(res.getPath());
JsonNode mySchema = JsonLoader.fromFile(file);
Run Code Online (Sandbox Code Playgroud)

  • `getClass().getResource("jsonschema.json")` 返回 `null`。我也试过`ClassPathResource res = new ClassPathResource("jsonschema.json")`,它只返回`jsonschema.json`。这与我使用 Spring Boot 有关系吗? (3认同)

cac*_*co3 15

如何可靠地获取资源

\n

要可靠地从 Spring Boot 应用程序中的资源获取文件:

\n
    \n
  1. 找到一种方法来传递抽象资源,例如 ,InputStreamURL不是File
  2. \n
  3. 使用框架设施获取资源
  4. \n
\n

示例:读取文件resources

\n
public class SpringBootResourcesApplication {\n    public static void main(String[] args) throws Exception {\n        ClassPathResource resource = new ClassPathResource("/hello", SpringBootResourcesApplication.class);\n        try (InputStream inputStream = resource.getInputStream()) {\n            String string = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8);\n            System.out.println(string);\n        }\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n
    \n
  • ClassPathResource是 Spring 的实现- 加载资源Resource的抽象方式。它是使用构造函数实例化的:ClassPathResource(String, Class<?>)

    \n\n
  • \n
  • 项目结构:

    \n
    \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 mvnw\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 mvnw.cmd\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 pom.xml\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 src\n    \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 main\n        \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 java\n        \xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 com\n        \xe2\x94\x82       \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 caco3\n        \xe2\x94\x82           \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 springbootresources\n        \xe2\x94\x82               \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 SpringBootResourcesApplication.java\n        \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 resources\n            \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 application.properties\n            \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 hello\n
    Run Code Online (Sandbox Code Playgroud)\n
  • \n
\n

上面的示例适用于 IDE 和 jar

\n

更深入的解释

\n
更喜欢抽象资源而不是File
\n
    \n
  • 抽象资源的例子是InputStreamURL
  • \n
  • 避免使用,File因为并不总是可以从类路径资源获取它\n
      \n
    • 例如,以下代码在 IDE 中运行:
    • \n
    \n
    \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 mvnw\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 mvnw.cmd\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 pom.xml\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 src\n    \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 main\n        \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 java\n        \xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 com\n        \xe2\x94\x82       \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 caco3\n        \xe2\x94\x82           \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 springbootresources\n        \xe2\x94\x82               \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 SpringBootResourcesApplication.java\n        \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 resources\n            \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 application.properties\n            \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 hello\n
    Run Code Online (Sandbox Code Playgroud)\n但失败并显示:\n
    java.nio.file.NoSuchFileException: file:/home/caco3/IdeaProjects/spring-boot-resources/target/spring-boot-resources-0.0.1-SNAPSHOT.jar!/BOOT-INF/classes!/hello\n        at java.base/sun.nio.fs.UnixException.translateToIOException(UnixException.java:92)\n        at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:111)\n        at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:116)\n
    Run Code Online (Sandbox Code Playgroud)\n当 Spring Boot jar 运行时
  • \n
  • 如果您使用外部库,并且它要求您提供资源,请尝试找到一种方法来传递它InputStreamURL\n
      \n
    • 例如,JsonLoader.fromFile问题中的 可以替换为JsonLoader.fromURL方法:它接受URL
    • \n
    \n
  • \n
\n
使用框架的设施来获取资源:
\n

Spring框架允许通过以下方式访问类路径资源ClassPathResource

\n

你可以使用它:

\n
    \n
  1. 直接,如读取文件的示例所示resources
  2. \n
  3. 间接:\n
      \n
    1. 使用@Value:\n
      public class SpringBootResourcesApplication {\n    public static void main(String[] args) throws Exception {\n        ClassLoader classLoader = SpringBootResourcesApplication.class.getClassLoader();\n        File file = new File(classLoader.getResource("hello").getFile());\n\n        Files.readAllLines(file.toPath(), StandardCharsets.UTF_8)\n                .forEach(System.out::println);\n    }\n}\n
      Run Code Online (Sandbox Code Playgroud)\n
    2. \n
    3. 使用ResourceLoader:\n
      java.nio.file.NoSuchFileException: file:/home/caco3/IdeaProjects/spring-boot-resources/target/spring-boot-resources-0.0.1-SNAPSHOT.jar!/BOOT-INF/classes!/hello\n        at java.base/sun.nio.fs.UnixException.translateToIOException(UnixException.java:92)\n        at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:111)\n        at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:116)\n
      Run Code Online (Sandbox Code Playgroud)\n
        \n
      • 另请参阅答案
      • \n
      \n
    4. \n
    \n
  4. \n
\n


小智 12

如果您在Resources文件夹下有例如config文件夹,那么我尝试过该类,希望可以很好地工作

File file = ResourceUtils.getFile("classpath:config/sample.txt")

//Read File Content
String content = new String(Files.readAllBytes(file.toPath()));
System.out.println(content);
Run Code Online (Sandbox Code Playgroud)

  • 我尝试了您的解决方案,它可以在IDE中使用,但是当您制作spring jar时,输入流会有所帮助。 (2认同)

Bha*_*kar 11

下面是我的工作代码。

List<sampleObject> list = new ArrayList<>();
File file = new ClassPathResource("json/test.json").getFile();
ObjectMapper objectMapper = new ObjectMapper();
sampleObject = Arrays.asList(objectMapper.readValue(file, sampleObject[].class));
Run Code Online (Sandbox Code Playgroud)

希望对大家有所帮助!


小智 9

在此处查看我的答案:https : //stackoverflow.com/a/56854431/4453282

import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
Run Code Online (Sandbox Code Playgroud)

使用这两个进口。

宣布

@Autowired
ResourceLoader resourceLoader;
Run Code Online (Sandbox Code Playgroud)

在某些功能中使用它

Resource resource=resourceLoader.getResource("classpath:preferences.json");
Run Code Online (Sandbox Code Playgroud)

在您的情况下,根据您的需要,您可以使用以下文件

File file = resource.getFile()

参考:http : //frugalisminds.com/spring/load-file-classpath-spring-boot/ 正如前面的答案中已经提到的,不要使用 ResourceUtils 它在部署 JAR 后不起作用,这也适用于 IDE部署后


Gov*_*ngh 6

陷入同样的​​问题,这对我有帮助

URL resource = getClass().getClassLoader().getResource("jsonschema.json");
JsonNode jsonNode = JsonLoader.fromURL(resource);
Run Code Online (Sandbox Code Playgroud)


Erç*_*çay 6

这是我的解决方案。可以帮助某人;

它返回 InputStream,但我假设您也可以从中读取。

InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("jsonschema.json");
Run Code Online (Sandbox Code Playgroud)


Mos*_*khi 5

在资源中创建json文件夹作为子文件夹,然后在文件夹中添加json文件,然后可以使用以下代码: 在此处输入图片说明

import com.fasterxml.jackson.core.type.TypeReference;

InputStream is = TypeReference.class.getResourceAsStream("/json/fcmgoogletoken.json");

这在Docker中有效。


归档时间:

查看次数:

106478 次

最近记录:

6 年,2 月 前