открыть ресурс с относительным путем в Java - PullRequest
73 голосов
/ 21 февраля 2009

В моем 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()

чтобы получить реальный путь, но этот путь не работает.

Понятия не имею, как сделать каталог.

Ответы [ 11 ]

139 голосов
/ 20 января 2010

У меня были проблемы с использованием метода 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")

Это больше не будет возвращать ноль, но вернет ваш класс. Надеюсь, это кому-нибудь поможет. Мне странно, что папка "resources" тоже не копируется, а только подпапки и файлы прямо в папке "resources". Мне кажется логичным, что папка "resources" также находится в папке "myapp/target/classes"

40 голосов
/ 21 февраля 2009

Укажите путь относительно загрузчика классов, а не класса, из которого вы получаете загрузчик. Например:

resourcesloader.class.getClassLoader().getResource("package1/resources/repository/SSL-Key/cert.jks").toString();
30 голосов
/ 20 июня 2011

В надежде предоставить дополнительную информацию тем, кто не подхватывает эту информацию так же быстро, как другие, я хотел бы представить свой сценарий, поскольку он имеет немного иную настройку. Мой проект был настроен со следующей структурой каталогов (с использованием Eclipse):

Project/
  src/                // application source code
    org/
      myproject/
        MyClass.java
  test/               // unit tests
  res/                // resources
    images/           // PNG images for icons
      my-image.png
    xml/              // XSD files for validating XML files with JAXB
      my-schema.xsd
    conf/             // default .conf file for Log4j
      log4j.conf
  lib/                // libraries added to build-path via project settings

У меня были проблемы с загрузкой моих ресурсов из каталога res . Я хотел, чтобы все мои ресурсы были отделены от моего исходного кода (просто для целей управления / организации). Итак, мне нужно было добавить каталог res в путь сборки и затем получить доступ к ресурсу через:

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 (String) вместо Class.getResource (String ) .

8 голосов
/ 21 октября 2010

@ Джанкарел: Вы можете попробовать вызвать системное свойство user.dir, которое даст вам корень вашего Java-проекта, а затем добавить этот путь к вашему относительному пути, например:

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);
7 голосов
/ 22 февраля 2009

Когда вы используете 'getResource' в классе, относительный путь разрешается на основе пакета, в котором находится класс. Когда вы используете 'getResource' в ClassLoader, относительный путь разрешается на основе корневой папки.

Если вы используете абсолютный путь, оба метода 'getResource' начнутся с корневой папки.

4 голосов
/ 27 октября 2015

Для тех, кто использует 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 из списка исходных папок проекта и вернув ее обратно (проект> свойства> путь сборки java> источник> удалить / добавить папку), я смог решить эту проблему.

2 голосов
/ 21 февраля 2009
resourcesloader.class.getClass()

Может быть разбит на:

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

Это означает, что вы пытаетесь загрузить ресурс с помощью класса начальной загрузки.

Вместо этого вы, вероятно, хотите что-то вроде:

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

Если бы только javac предупреждал о вызове статических методов в нестатических контекстах ...

1 голос
/ 11 декабря 2011

Идем с двумя ответами, как упомянуто выше. Первый

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

Должно быть одно и то же?

1 голос
/ 21 февраля 2009

Следующие работы?

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

Существует ли причина, по которой вы не можете указать полный путь, включая пакет?

0 голосов
/ 28 февраля 2017

Используйте это:

resourcesloader.class.getClassLoader().getResource("/path/to/file").**getPath();**
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...