source

Spring Boot의 Resources 폴더에서 파일 읽기

lovecheck 2023. 3. 8. 21:16
반응형

Spring Boot의 Resources 폴더에서 파일 읽기

과 Spring Boot을 json-schema-validator called called called called called called called called called called called called called called called called called called called called jsonschema.json resources 않아요.여러 가지 방법을 시도해 봤지만 효과가 없어요.이건 내 암호야

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

여기가 파일 위치입니다.

여기에 이미지 설명 입력

여기 '요'파일이 요.classes더입니니다다

여기에 이미지 설명 입력

그러나 코드를 실행하면 다음과 같은 오류가 발생합니다.

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

내 코드에서 내가 뭘 잘못하고 있는 거지?

오랜 시간을 들여 이 문제를 해결한 끝에, 드디어 유효한 솔루션을 찾았습니다.이 솔루션에서는 Spring의 Resource Utils를 사용합니다.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;
    }
}

코멘트에 관한 몇 가지 우려 사항에 답변하려면:

Amazon 에서 Amazon EC2를 사용하여 합니다.java -jar target/image-service-slave-1.0-SNAPSHOT.jar

JAR에서 실행하는 올바른 방법을 알아보려면 my github repo: https://github.com/johnsanthosh/image-service를 참조하십시오.

매우 짧은 답변: 타겟 클래스가 아닌 클래스로더 클래스의 범위에서 리소스를 찾고 있습니다.이 조작은 유효합니다.

File file = new File(getClass().getResource("jsonschema.json").getFile());
JsonNode mySchema = JsonLoader.fromFile(file);

또한 다음 내용을 읽으면 도움이 될 수 있습니다.

추신: 프로젝트를 한 기계로 컴파일한 후 다른 기계 또는 도커 내부에서 실행한 경우가 있습니다.이러한 시나리오에서는 리소스 폴더에 대한 경로가 잘못되어 런타임에 가져와야 합니다.

ClassPathResource res = new ClassPathResource("jsonschema.json");    
File file = new File(res.getPath());
JsonNode mySchema = JsonLoader.fromFile(file);

2020년부터 갱신

또한 테스트 등에서 리소스 파일을 문자열로 읽는 경우 다음과 같은 static utils 메서드를 사용할 수 있습니다.

public static String getResourceFileAsString(String fileName) {
    InputStream is = getResourceFileAsInputStream(fileName);
    if (is != null) {
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        return (String)reader.lines().collect(Collectors.joining(System.lineSeparator()));
    } else {
        throw new RuntimeException("resource not found");
    }
}

public static InputStream getResourceFileAsInputStream(String fileName) {
    ClassLoader classLoader = {CurrentClass}.class.getClassLoader();
    return classLoader.getResourceAsStream(fileName);
}

사용 예:

String soapXML = getResourceFileAsString("some_folder_in_resources/SOPA_request.xml");

예를 들어 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);

이 페이지로 돌아오는 데 너무 많은 시간을 소비했으므로 이 페이지는 여기에 남겨두겠습니다.

File file = new ClassPathResource("data/data.json").getFile();

2021년 최고의 방법


파일을 읽는 가장 간단한 방법은 다음과 같습니다.

    Resource resource = new ClassPathResource("jsonSchema.json");
    FileInputStream file = new FileInputStream(resource.getFile());

답변은 이쪽에서 보실 수 있습니다.https://stackoverflow.com/a/56854431/4453282

import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;

이 2개의 Import를 사용합니다.

선언하다

@Autowired
ResourceLoader resourceLoader;

일부 기능에서 사용

Resource resource=resourceLoader.getResource("classpath:preferences.json");

당신의 경우 파일이 필요하기 때문에 다음 파일을 사용할 수 있습니다.

File file = resource.getFile()

레퍼런스: http://frugalisminds.com/spring/load-file-classpath-spring-boot/ 이전 답변에서 설명한 바와 같이 Resource Utils를 사용하지 않습니다.JAR 도입 후 동작하지 않습니다.이것은 IDE에서도 전개 후에도 동작합니다.

아래는 제 작업 코드입니다.

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

도움이 됐으면 좋겠네요!

자원을 안정적으로 입수하는 방법

Spring Boot 응용 프로그램의 리소스에서 파일을 안정적으로 가져오려면 다음 절차를 수행합니다.

  1. 인 자원을 전달할 방법을 . 예를 인 자원을 전달할 방법을 .InputStream,URLFile
  2. 프레임워크 기능을 사용하여 리소스 가져오기

: 에서 .resources

public class SpringBootResourcesApplication {
    public static void main(String[] args) throws Exception {
        ClassPathResource resource = new ClassPathResource("/hello", SpringBootResourcesApplication.class);
        try (InputStream inputStream = resource.getInputStream()) {
            String string = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8);
            System.out.println(string);
        }
    }
}
  • ClassPathResource Spring의 구현입니다.Resource- 리소스를 로드하는 추상적인 방법.생성자를 사용하여 인스턴스화됩니다.

    • /hello파일 경로입니다.
      • 선두 슬래시는 클래스 경로의 절대 경로를 기준으로 파일을 로드합니다.
    • 는 " " 입니다.Class원을적적적적
  • 프로젝트 구조:

    ├── mvnw
    ├── mvnw.cmd
    ├── pom.xml
    └── src
        └── main
            ├── java
            │   └── com
            │       └── caco3
            │           └── springbootresources
            │               └── SpringBootResourcesApplication.java
            └── resources
                ├── application.properties
                └── hello
    

위의 예는 IDE와 jar에서 모두 동작합니다.

상세설명

합니다.File
  • 추상 자원의 예는 다음과 같습니다.InputStream ★★★★★★★★★★★★★★★★★」URL
  • File클래스 패스 리소스에서 항상 가져올 수 있는 것은 아니기 때문입니다.
    • 예: IDE에서는 다음 코드가 동작합니다.
    public class SpringBootResourcesApplication {
        public static void main(String[] args) throws Exception {
            ClassLoader classLoader = SpringBootResourcesApplication.class.getClassLoader();
            File file = new File(classLoader.getResource("hello").getFile());
    
            Files.readAllLines(file.toPath(), StandardCharsets.UTF_8)
                    .forEach(System.out::println);
        }
    }
    
    실패하면 '어,어,어,어,어,어,어,어,어,어,어,
    java.nio.file.NoSuchFileException: file:/home/caco3/IdeaProjects/spring-boot-resources/target/spring-boot-resources-0.0.1-SNAPSHOT.jar!/BOOT-INF/classes!/hello
            at java.base/sun.nio.fs.UnixException.translateToIOException(UnixException.java:92)
            at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:111)
            at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:116)
    
    jar run Spring Boot jar " " " 。
  • 했을 때, 라이브러리가 , 이 .InputStream ★★★★★★★★★★★★★★★★★」URL
    • 를 들면, 「 」입니다.JsonLoader.fromFile질문에서 수법으로 대체될 수 있다: 그것은 그것을 받아들인다.URL
프레임워크의 기능을 사용하여 리소스를 가져옵니다.

Spring Framework를 통해 클래스 패스 리소스에 액세스할 수 있습니다.

사용할 수 있습니다.

  1. 에서 직접resources
  2. ★★★★★★★★★★★★★★★★★★:
    1. 사용방법:
      @SpringBootApplication
      public class SpringBootResourcesApplication implements ApplicationRunner {
          @Value("classpath:/hello") // Do not use field injection
          private Resource resource;
      
          public static void main(String[] args) throws Exception {
              SpringApplication.run(SpringBootResourcesApplication.class, args);
          }
      
         @Override
         public void run(ApplicationArguments args) throws Exception {
             try (InputStream inputStream = resource.getInputStream()) {
                 String string = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8);
                 System.out.println(string);
             }
         }
      }
      
    2. 사용방법:
      @SpringBootApplication
      public class SpringBootResourcesApplication implements ApplicationRunner {
          @Autowired // do not use field injection
          private ResourceLoader resourceLoader;
      
          public static void main(String[] args) throws Exception {
              SpringApplication.run(SpringBootResourcesApplication.class, args);
          }
      
          @Override
          public void run(ApplicationArguments args) throws Exception {
              Resource resource = resourceLoader.getResource("/hello");
              try (InputStream inputStream = resource.getInputStream()) {
                  String string = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8);
                  System.out.println(string);
              }
          }
      }
      
      • 답변도 참조해 주세요.

같은 이슈에 갇힌다면, 이것은 나에게 도움이 된다.

URL resource = getClass().getClassLoader().getResource("jsonschema.json");
JsonNode jsonNode = JsonLoader.fromURL(resource);

리소스에서 하위 폴더로 json 폴더를 생성한 다음 폴더에 json 파일을 추가하면 다음 코드를 사용할 수 있습니다.

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

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

이것은 도커에서 동작합니다.

제 해결책은 이렇습니다.누군가를 도울 수 있다.

InputStream이 반환되지만, 읽어보실 수도 있습니다.

InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("jsonschema.json");

리소스 디렉토리의 클래스 경로에서 String으로 리소스를 가져오는 가장 간단한 방법은 다음 라이너입니다.

문자열(스프링 라이브러리 사용):

         String resource = StreamUtils.copyToString(
                new ClassPathResource("resource.json").getInputStream(), defaultCharset());

이 메서드는 StreamUtils 유틸리티를 사용하여 파일을 입력 스트림으로 String에 간결하게 스트리밍합니다.

파일을 바이트 배열로 사용하려면 기본 Java 파일 I/O 라이브러리를 사용할 수 있습니다.

바이트 배열(Java 라이브러리 사용):

byte[] resource = Files.readAllBytes(Paths.get("/src/test/resources/resource.json"));

사용하시는 경우spring그리고.jackson(대부분의 큰 어플리케이션에서는) 심플한 oneliner를 사용합니다.

JsonNode json = new ObjectMapper().readTree(new ClassPathResource("filename").getFile());

여기 다음 해결 방법이 있습니다.ResourceUtils및 Java 11Files.readStringUTF-8 인코딩 및 리소스 클로징을 처리합니다.

import static java.nio.charset.StandardCharsets.UTF_8;
import static org.springframework.util.FileCopyUtils.copyToByteArray;
import org.springframework.core.io.ClassPathResource;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

public  JsonNode getJsonData() throws IOException {
  ClassPathResource classPathResource = new 
  ClassPathResource("assets/data.json");
        byte[] byteArray = 
  copyToByteArray(classPathResource.getInputStream());
        return new ObjectMapper() //
                .readTree(new String(byteArray, UTF_8));
}

또는 더 심플한

스텝 1: 자원 파일을 만듭니다.예를 들어 /src/main/resources/data/test.data에 입력합니다.
스텝 2 : 값을 정의합니다.application.properties/yml

com.test.package.data=#{new org.springframework.core.io.ClassPathResource("/data/test.data").getFile().getAbsolutePath()}

순서 3: 코드로 파일을 가져옵니다.

@Value("${com.test.package.data}")
private String dataFile;

private void readResourceFile() {
   Path path = Paths.get(dataFile);
   List<String> allLines = Files.readAllLines(path);
}

봄은 제공한다.ResourceLoader파일을 로드하는 데 사용할 수 있습니다.

@Autowired
ResourceLoader resourceLoader;


// path could be anything under resources directory
File loadDirectory(String path){
        Resource resource = resourceLoader.getResource("classpath:"+path); 
        try {
            return resource.getFile();
        } catch (IOException e) {
            log.warn("Issue with loading path {} as file", path);
        }
        return null;
 }

링크를 참조.

다른 모든 답변과 함께 2센트를 더하는 것 뿐이죠.Spring Default Resource Loader를 사용하여 Resource Loader를 가져옵니다.그런 다음 Spring FileCopyUtils를 사용하여 리소스 파일의 내용을 문자열로 가져옵니다.

import static java.nio.charset.StandardCharsets.UTF_8;

import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.UncheckedIOException;

import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.util.FileCopyUtils;

public class ResourceReader {
    public static String readResourceFile(String path) {
        ResourceLoader resourceLoader = new DefaultResourceLoader();
        Resource resource = resourceLoader.getResource(path);
        return asString(resource);
    }

    private static String asString(Resource resource) {
        try (Reader reader = new InputStreamReader(resource.getInputStream(), UTF_8)) {
            return FileCopyUtils.copyToString(reader);
        } catch (IOException e) {
            throw new UncheckedIOException(e);
        }
    }
}

저에게 버그는 두 가지 수정이 있었습니다.

  1. SAMPLE이라는 이름의 XML 파일.AWS ec2에 전개했을 때, 이하의 솔루션에서도 장해가 발생하고 있는 XML.수정은 new_sample.xml로 이름을 변경하고 아래에 제시된 솔루션을 적용하는 것이었습니다.
  2. 솔루션 접근법 https://medium.com/ @syslog.syslog/reading-files-in-resource-path-from-jar-459ce00d2130

Spring boot을 jar로 사용하여 다음과 같은 솔루션의 aWS ec2 Java variant에 배포했습니다.

package com.test;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.Resource;


public class XmlReader {

    private static Logger LOGGER = LoggerFactory.getLogger(XmlReader.class);

  public static void main(String[] args) {


      String fileLocation = "classpath:cbs_response.xml";
      String reponseXML = null;
      try (ClassPathXmlApplicationContext appContext = new ClassPathXmlApplicationContext()){

        Resource resource = appContext.getResource(fileLocation);
        if (resource.isReadable()) {
          BufferedReader reader =
              new BufferedReader(new InputStreamReader(resource.getInputStream()));
          Stream<String> lines = reader.lines();
          reponseXML = lines.collect(Collectors.joining("\n"));

        }      
      } catch (IOException e) {
        LOGGER.error(e.getMessage(), e);
      }
  }
}

maven resource filter를 proyect에서 사용하는 경우 pom.xml에 로드되는 파일의 종류를 설정해야 합니다.그렇지 않으면 리소스를 로드하도록 선택한 클래스에 관계없이 리소스를 찾을 수 없습니다.

pom.xml

<resources>
    <resource>
        <directory>${project.basedir}/src/main/resources</directory>
        <filtering>true</filtering>
        <includes>
            <include>**/*.properties</include>
            <include>**/*.yml</include>
            <include>**/*.yaml</include>
            <include>**/*.json</include>
        </includes>
    </resource>
</resources>

아래는 IDE와 단말기의 jar로 동작하는 양쪽 모두에서 동작합니다.

import org.springframework.core.io.Resource;

@Value("classpath:jsonschema.json")
Resource schemaFile;
    
JsonSchemaFactory factory = JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V4);
JsonSchema jsonSchema = factory.getSchema(schemaFile.getInputStream());

경로를 삭제하고 %20을 공백으로 바꾸거나 디렉터리 이름을 변경해야 합니다.그럼 효과가 있을 거야

FileNotFoundException: /home/user/Dev/Java/Java%20Programs/SystemRoutines/target/classes/jsonschema.json

문제는 당신의 프로젝트가 있는 폴더 이름 안에 있는 공간에 있다고 생각합니다./home/user/Dev/Java/Java%20 Programs/SystemRoutines/target/classes/jsonschema.json

Java 프로그램 사이에 공백이 있습니다.폴더 이름을 바꾸면 작동합니다.

Spring ResourceUtils.getFile()을 사용하면 절대 경로를 주의할 필요가 없습니다. : )

 private String readDictionaryAsJson(String filename) throws IOException {
    String fileContent;
    try {
        File file = ResourceUtils.getFile("classpath:" + filename);
        Path path = file.toPath();
        Stream<String> lines = Files.lines(path);
        fileContent = lines.collect(Collectors.joining("\n"));
    } catch (IOException ex) {
        throw ex;
    }
    return new fileContent;
}

이것을 시험해 보세요.

application.properties에서

app.jsonSchema=classpath:jsonschema.json

속성에서 pojo:

메모: application.properties에서 원하는 방법으로 설정을 읽을 수 있습니다.

@Configuration
@ConfigurationProperties(prefix = "app") 
public class ConfigProperties {
private Resource jsonSchema;

// standard getters and setters
}

수업 시간에 속성 Pojo의 리소스를 읽습니다.

//Read the Resource and get the Input Stream
try (InputStream inStream = configProperties.getJsonSchema().getInputStream()) {
   //From here you can manipulate the Input Stream as desired....
   //Map the Input Stream to a Map
    ObjectMapper mapper = new ObjectMapper();
    Map <String, Object> jsonMap = mapper.readValue(inStream, Map.class);
    //Convert the Map to a JSON obj
    JSONObject json = new JSONObject(jsonMap);
    } catch (Exception e) {
        e.printStackTrace();
    }

현재, 2023년에는 Java 사용자가 클래스 경로 파일을 더 쉽게 읽을 수 있게 될 것입니다. such음음 as as as as as as 등의 간단한 new File("classpath:path-to-file").

저도 같은 문제가 있어서 파일 입력 스트림에 보낼 파일 경로를 얻어야 했기 때문에 이렇게 했습니다.

    String pfxCertificate ="src/main/resources/cert/filename.pfx";
    String pfxPassword = "1234";
    FileInputStream fileInputStream = new FileInputStream(pfxCertificate));

언급URL : https://stackoverflow.com/questions/44399422/read-file-from-resources-folder-in-spring-boot

반응형