code

자바에서 상대 경로로 리소스 열기

codestyles 2020. 10. 20. 07:39
반응형

자바에서 상대 경로로 리소스 열기


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

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

나는 디렉토리를 어떻게하는지 모른다.


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

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 (문자열) .


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

When you use 'getResource' on a Class, a relative path is resolved based on the package the Class is in. When you use 'getResource' on a ClassLoader, a relative path is resolved based on the root folder.

If you use an absolute path, both 'getResource' methods will start at the root folder.


For those using eclipse + maven. Say you try to access the file images/pic.jpg in src/main/resources. Doing it this way :

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

is perfectly correct, but may result in a null pointer exception. Seems like eclipse doesn't recognize the folders in the maven directory structure as source folders right away. By removing and the src/main/resources folder from the project's source folders list and putting it back (project>properties>java build path> source>remove/add Folder), I was able to solve this.


resourcesloader.class.getClass()

Can be broken down to:

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

Which means you're trying to load the resource using a bootstrap class.

Instead you probably want something like:

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

If only javac warned about calling static methods on non-static contexts...


Doe the following work?

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

Is there a reason you can't specify the full path including the package?


Going with the two answers as mentioned above. The first one

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

Should be one and same thing?


I made a small modification on @jonathan.cone's one liner ( by adding .getFile() ) to avoid null pointer exception, and setting the path to data directory. Here's what worked for me :

String realmID = new java.util.Scanner(new java.io.File(RandomDataGenerator.class.getClassLoader().getResource("data/aa-qa-id.csv").getFile().toString())).next();

Use this:

resourcesloader.class.getClassLoader().getResource("/path/to/file").**getPath();**

In Order to obtain real path to the file you can try this:

URL fileUrl = Resourceloader.class.getResource("resources/repository/SSL-Key/cert.jks");
String pathToClass = fileUrl.getPath;    

Resourceloader is classname here. "resources/repository/SSL-Key/cert.jks" is relative path to the file. If you had your guiclass in ./package1/java with rest of folder structure remaining, you would take "../resources/repository/SSL-Key/cert.jks" as relative path because of rules defining relative path.

This way you can read your file with BufferedReader. DO NOT USE THE STRING to identify the path to the file, because if you have spaces or some characters from not english alphabet in your path, you will get problems and the file will not be found.

BufferedReader bufferedReader = new BufferedReader(
                        new InputStreamReader(fileUrl.openStream()));

참고URL : https://stackoverflow.com/questions/573679/open-resource-with-relative-path-in-java

반응형