[java] Java의 클래스 경로에서 텍스트 파일을 실제로 읽는 방법

CLASSPATH 시스템 변수에 설정된 텍스트 파일을 읽으려고합니다. 사용자 변수가 아닙니다.

아래와 같이 파일에 입력 스트림을 가져 오려고합니다.

D:\myDirCLASSPATH 에 파일 ( ) 의 디렉토리를 배치 하고 아래에서 시도하십시오.

InputStream in = this.getClass().getClassLoader().getResourceAsStream("SomeTextFile.txt");
InputStream in = this.getClass().getClassLoader().getResourceAsStream("/SomeTextFile.txt");
InputStream in = this.getClass().getClassLoader().getResourceAsStream("//SomeTextFile.txt");

파일의 전체 경로 ( D:\myDir\SomeTextFile.txt)를 CLASSPATH에 놓고 위의 3 줄의 코드를 동일하게 시도하십시오.

그러나 불행히도 그들 중 아무도 작동하지 않으며 항상 nullInputStream에 들어가고 in있습니다.



답변

동일한 클래스 로더가로드 한 클래스에서 클래스 경로에 디렉토리가 있으면 다음 중 하나를 사용할 수 있습니다.

// From ClassLoader, all paths are "absolute" already - there's no context
// from which they could be relative. Therefore you don't need a leading slash.
InputStream in = this.getClass().getClassLoader()
                                .getResourceAsStream("SomeTextFile.txt");
// From Class, the path is relative to the package of the class unless
// you include a leading slash, so if you don't want to use the current
// package, include a slash like this:
InputStream in = this.getClass().getResourceAsStream("/SomeTextFile.txt");

그것들이 작동하지 않으면 다른 것이 잘못되었음을 나타냅니다.

예를 들어 다음 코드를 사용하십시오.

package dummy;

import java.io.*;

public class Test
{
    public static void main(String[] args)
    {
        InputStream stream = Test.class.getResourceAsStream("/SomeTextFile.txt");
        System.out.println(stream != null);
        stream = Test.class.getClassLoader().getResourceAsStream("SomeTextFile.txt");
        System.out.println(stream != null);
    }
}

그리고이 디렉토리 구조 :

code
    dummy
          Test.class
txt
    SomeTextFile.txt

그런 다음 (Linux 상자에서 유닉스 경로 구분 기호를 사용하여) :

java -classpath code:txt dummy.Test

결과 :

true
true


답변

스프링 프레임 워크를 사용할 때 (유틸리티 또는 컨테이너 의 모음으로 -후자의 기능을 사용할 필요가 없음) 자원 추상화를 쉽게 사용할 수 있습니다 .

Resource resource = new ClassPathResource("com/example/Foo.class");

Resource 인터페이스를 통해 InputStream , URL , URI 또는 File 로 리소스에 액세스 할 수 있습니다 . 예를 들어 파일 시스템 리소스로 리소스 유형을 변경하는 것은 인스턴스를 변경하는 간단한 문제입니다.


답변

다음은 Java 7 NIO를 사용하여 클래스 경로에서 텍스트 파일의 모든 줄을 읽는 방법입니다.

...
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;

...

Files.readAllLines(
    Paths.get(this.getClass().getResource("res.txt").toURI()), Charset.defaultCharset());

NB 이것은 어떻게 할 수 있는지의 예입니다. 필요에 따라 개선해야합니다. 이 예제는 파일이 실제로 클래스 경로에있는 경우에만 작동합니다. 그렇지 않으면 getResource ()가 null을 반환하고 .toURI ()가 호출 될 때 NullPointerException이 발생합니다.

또한 Java 7부터 문자 세트를 지정하는 편리한 방법 중 하나는 정의 된 상수를 사용하는 java.nio.charset.StandardCharsets
것입니다. javadocs “Java 플랫폼의 모든 구현에서 사용 가능함”).

따라서 파일의 인코딩이 UTF-8임을 알고 있으면 명시 적으로 문자 세트를 지정하십시오. StandardCharsets.UTF_8


답변

시도하십시오

InputStream in = this.getClass().getResourceAsStream("/SomeTextFile.txt");

만 클래스 로더 때문에 귀하의 시도가 작동하지 않았다 당신의 클래스는 클래스 경로에서로드 할 수 있습니다. Java 시스템 자체에 클래스 로더를 사용했습니다.


답변

실제로 파일의 내용을 읽으려면 Commons IO + Spring Core를 사용하는 것이 좋습니다. 자바 8 :

try (InputStream stream = new ClassPathResource("package/resource").getInputStream()) {
    IOUtils.toString(stream);
}

또는

InputStream stream = null;
try {
    stream = new ClassPathResource("/log4j.xml").getInputStream();
    IOUtils.toString(stream);
} finally {
    IOUtils.closeQuietly(stream);
}


답변

클래스 절대 경로를 얻으려면 다음을 시도하십시오.

String url = this.getClass().getResource("").getPath();


답변

어쨌든 가장 좋은 대답은 효과가 없습니다. 대신 약간 다른 코드를 사용해야합니다.

ClassLoader loader = Thread.currentThread().getContextClassLoader();
InputStream is = loader.getResourceAsStream("SomeTextFile.txt");

나는 이것이 같은 문제가 발생하는 사람들에게 도움이되기를 바랍니다.