[java] Java에서 상대 경로로 리소스 열기

Java 앱에서 파일과 디렉토리를 가져와야합니다.

다음은 프로그램 구조입니다.

./main.java
./package1/guiclass.java
./package1/resources/resourcesloader.java
./package1/resources/repository/modules/   -> this is the dir I need to get
./package1/resources/repository/SSL-Key/cert.jks    -> this is the file I need to get

guiclass 내 리소스 (디렉토리 및 파일)를로드 할 resourcesloader 클래스를로드합니다.

파일에 관해서는

resourcesloader.class.getClass().getResource("repository/SSL-Key/cert.jks").toString()

실제 경로를 얻으려면이 방법은 작동하지 않습니다.

디렉토리에 어떤 경로를 사용할지 모르겠습니다.

a


답변

로더를 가져 오는 클래스가 아니라 클래스 로더에 상대적인 경로를 제공하십시오. 예를 들면 :

resourcesloader.class.getClassLoader().getResource("package1/resources/repository/SSL-Key/cert.jks").toString();


답변

getClass().getResource("filename.txt")방법 을 사용하는 데 문제가있었습니다 . Java 문서 지침을 읽을 때 리소스가 리소스에 액세스하려는 클래스와 동일한 패키지에 있지 않은 경우로 시작하는 상대 경로를 제공해야합니다 '/'. 권장되는 전략은 리소스 파일을 루트 디렉터리의 “resources”폴더에 저장하는 것입니다. 예를 들어 구조가있는 경우 :

src/main/com/mycompany/myapp

그런 다음 maven이 권장하는대로 리소스 폴더를 추가 할 수 있습니다.

src/main/resources

또한 리소스 폴더에 하위 폴더를 추가 할 수 있습니다.

src/main/resources/textfiles

당신의 파일이라고 말할 myfile.txt당신이 그래서

src/main/resources/textfiles/myfile.txt

이제 여기에서 어리석은 경로 문제가 발생합니다.에 클래스가 있고 리소스 폴더에서 파일 com.mycompany.myapp package에 액세스하려고 한다고 가정 myfile.txt합니다. 일부는 다음을 제공해야한다고 말합니다.

"/main/resources/textfiles/myfile.txt" path

또는

"/resources/textfiles/myfile.txt"

둘 다 잘못되었습니다. 을 실행 mvn clean compile하면 파일과 폴더가 다음 위치에 복사됩니다.

myapp/target/classes

폴더. 그러나 리소스 폴더는 거기에 있지 않고 리소스 폴더의 폴더 만 있습니다. 그래서 당신은 :

myapp/target/classes/textfiles/myfile.txt

myapp/target/classes/com/mycompany/myapp/*

따라서 getClass().getResource("")메서드 에 제공 할 올바른 경로 는 다음과 같습니다.

"/textfiles/myfile.txt"

여기있어:

getClass().getResource("/textfiles/myfile.txt")

더 이상 null을 반환하지 않지만 클래스를 반환합니다. 누군가에게 도움이되기를 바랍니다. "resources"폴더도 복사되지 않고 폴더에 직접 하위 폴더와 파일 만 있다는 것이 이상 "resources"합니다. "resources"폴더도 아래에서 찾을 수 있다는 것이 논리적으로 보입니다."myapp/target/classes"


답변

다른 사람들만큼 빨리 익히지 않는 사람들에게 추가 정보를 제공하기 위해 약간 다른 설정을 가지고있는 시나리오를 제공하고 싶습니다. 내 프로젝트는 다음 디렉터리 구조로 설정되었습니다 (Eclipse 사용).

계획/
  src / // 애플리케이션 소스 코드
    org /
      myproject /
        MyClass.java
  test / // 단위 테스트
  res / // 리소스
    images / // 아이콘 용 PNG 이미지
      my-image.png
    xml / // JAXB로 XML 파일의 유효성을 검사하기위한 XSD 파일
      my-schema.xsd
    conf / // Log4j 용 기본 .conf 파일
      log4j.conf
  lib / // 프로젝트 설정을 통해 빌드 경로에 추가 된 라이브러리

res 디렉토리 에서 내 리소스를로드하는 데 문제가있었습니다 . 모든 리소스를 소스 코드와 분리하기를 원했습니다 (간단히 관리 / 조직 목적). 그래서 내가해야 할 일은 res 디렉토리를 build-path 에 추가 한 다음 다음을 통해 리소스에 액세스하는 것입니다.

static final ClassLoader loader = MyClass.class.getClassLoader();

// in some function
loader.getResource("images/my-image.png");
loader.getResource("xml/my-schema.xsd");
loader.getResource("conf/log4j.conf");

참고 :/ 내가 사용하고 있기 때문에 리소스 문자열의 처음부터 생략 ClassLoader.getResource (문자열) 대신 Class.getResource (문자열) .


답변

Class에서 ‘getResource’를 사용하면 Class가 속한 패키지를 기준으로 상대 경로가 결정됩니다. ClassLoader에서 ‘getResource’를 사용하면 루트 폴더를 기준으로 상대 경로가 결정됩니다.

절대 경로를 사용하는 경우 두 ‘getResource’메소드가 모두 루트 폴더에서 시작됩니다.


답변

@GianCarlo : Java 프로젝트의 루트를 제공하는 시스템 속성 user.dir을 호출 한 다음이 경로를 상대 경로에 추가 할 수 있습니다. 예를 들면 다음과 같습니다.

String root = System.getProperty("user.dir");
String filepath = "/path/to/yourfile.txt"; // in case of Windows: "\\path \\to\\yourfile.txt
String abspath = root+filepath;



// using above path read your file into byte []
File file = new File(abspath);
FileInputStream fis = new FileInputStream(file);
byte []filebytes = new byte[(int)file.length()];
fis.read(filebytes);


답변

eclipse + maven을 사용하는 사람들을 위해. 에서 파일 images/pic.jpg에 액세스하려고한다고 가정 해 보겠습니다 src/main/resources. 이 방법으로 수행 :

ClassLoader loader = MyClass.class.getClassLoader();
File file = new File(loader.getResource("images/pic.jpg").getFile());

완벽하게 정확하지만 널 포인터 예외가 발생할 수 있습니다. eclipse는 maven 디렉토리 구조의 폴더를 소스 폴더로 즉시 인식하지 못하는 것 같습니다. src/main/resources프로젝트의 소스 폴더 목록에서 폴더 를 제거하고 다시 넣어서 (프로젝트> 속성> 자바 빌드 경로> 소스> 폴더 제거 / 추가)이 문제를 해결할 수있었습니다.


답변

resourcesloader.class.getClass()

다음과 같이 나눌 수 있습니다.

Class<resourcesloader> clazz = resourceloader.class;
Class<Class> classClass = clazz.getClass();

즉, 부트 스트랩 클래스를 사용하여 리소스를로드하려고합니다.

대신 다음과 같은 것을 원할 것입니다.

resourcesloader.class.getResource("repository/SSL-Key/cert.jks").toString()

비 정적 컨텍스트에서 정적 메서드를 호출하는 것에 대해 javac 만 경고했다면 …


댓글 달기

이메일 주소를 발행하지 않을 것입니다. 필수 항목은 *(으)로 표시합니다