Открыть ресурс с относительным путем в 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()

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

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

Ответ 1

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

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

Ответ 2

У меня возникли проблемы с использованием метода getClass().getResource("filename.txt"). После чтения инструкций к документам Java, если ваш ресурс не находится в том же пакете, что и класс, к которому вы пытаетесь получить доступ к ресурсу, тогда вы должны указать его относительный путь, начиная с '/'. Рекомендуемая стратегия заключается в том, чтобы поместить файлы ресурсов в папку "resources" в корневом каталоге. Так, например, если у вас есть структура:

src/main/com/mycompany/myapp

то вы можете добавить папку ресурсов в соответствии с рекомендациями maven in:

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"

Ответ 3

В надежде предоставить дополнительную информацию тем, кто не выбирает это так быстро, как другие, я хотел бы предоставить свой сценарий, поскольку он имеет немного другую настройку. Мой проект был настроен со следующей структурой каталогов (с использованием 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).

Ответ 4

@GianCarlo: Вы можете попробовать вызвать Системное свойство 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);

Ответ 5

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

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

Ответ 6

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

Ответ 7

resourcesloader.class.getClass()

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

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

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

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

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

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

Ответ 8

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

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

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

Ответ 9

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

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

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

Ответ 10

Я сделал небольшую модификацию на @jonathan.cone один лайнер (добавив .getFile()), чтобы исключить исключение нулевого указателя и установить путь к каталогу данных. Вот то, что сработало для меня:

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

Ответ 11

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

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

Ответ 12

Чтобы получить реальный путь к файлу, вы можете попробовать это:

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

Resourceloader - это имя класса здесь. "resources/repository/SSL-Key/cert.jks" - это относительный путь к файлу. Если бы у вас был гитарный класс в. /package1/java с оставшейся структурой папки, то вы бы взяли "../resources/repository/SSL-Key/cert.jks" в качестве относительного пути из-за правил, определяющих относительный путь.

Таким образом, вы можете прочитать ваш файл с BufferedReader. НЕ ИСПОЛЬЗУЙТЕ СТРОКУ, чтобы определить путь к файлу, потому что, если в вашем пути есть пробелы или некоторые символы не из английского алфавита, у вас возникнут проблемы, и файл не будет найден.

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