Я пытаюсь импортировать файл для использования в моем простом проекте Java. В настоящее время я использую IntelliJ в качестве IDEE и Gradle для создания проекта.
Проблема:
Когда я пытаюсь проверить, загружает ли программа ресурсы, используя
URL url = getClass().getClassLoader().getResource(filePath);
функция, передавая «src/main/resources/File» в качестве аргумента, она работает нормально, поскольку я создаю приложение (используя Gradle) и запускаю его через IntelliJ.
Однако, когда я пытаюсь заставить его работать с классом, запущенным через терминал, задача FAIL, потому что она не может найти файл ресурсов, поскольку функция возвращает Null.
Вот мое дерево путей:
├── build
│ ├── classes
│ │ └── java
│ │ └── main
│ │ └── it
│ │ └── uni
│ │ └── cs
│ │ └── name
│ │ └── progettofinaledatemplate
│ │ ├── controller
│ │ ├── models
│ │ └── view
│ ├── distributions
│ ├── generated
│ │ └── sources
│ │ ├── annotationProcessor
│ │ │ └── java
│ │ │ └── main
│ │ └── headers
│ │ └── java
│ │ └── main
│ ├── libs
│ ├── resources
│ │ └── main
│ │ └── it
│ │ └── uni
│ │ └── cs
│ │ └── name
│ │ └── progettofinaledatemplate->resources files
│ ├── scripts
│ └── tmp
│ ├── compileJava
│ │ └── compileTransaction
│ │ ├── backup-dir
│ │ └── stash-dir
│ └── jar
├── gradle
│ └── wrapper
└── src
└── main
├── java
│ └── it
│ └── uni
│ └── cs
│ └── name
│ └── progettofinaledatemplate
│ ├── controller
│ ├── models
│ └── view
└── resources
└── it
└── uni
└── cs
└── name
└── progettofinaledatemplate->resources files
Извините, если повторил уже существующую тему, но не нашел решения.
Что я пробовал:
sourceSets {
main {
resources {
srcDir 'src/main/resources'
}
}
}
Для начала не используйте имя «filePath» в getResource(filePath)
. Перестаньте думать об этом как о файле; это ресурс. Когда вы создаете свое приложение, все, что находится в каталоге resources
, помещается в корень вашего jar-файла. У вас должна быть возможность получить доступ к своему ресурсу, используя getResource("/File")
(то есть оставьте бит src/main/resources
).
Вы почти никогда не захотите иметь такой уровень вложенности в ресурсы. Нет необходимости зеркально отображать дерево пакетов.
Спасибо за ответы, я использовал getResource("/FileName");
, но все равно возвращаю Null. Однако на этот раз запуск приложения через IntelliJ вернет значение Null. Я уверен, что проблема не в формате ресурса. Еще раз спасибо @k314159
Вы используете неправильный URL для загрузки ресурсов. Измените путь к URL-адресу, который будет полностью соответствовать вашим запросам. Это ответ на вашу проблему.
Было бы полезно, если бы вы указали фактическое имя файла, а не какой-то загадочный заполнитель.
Кажется, вы используете неправильное имя/путь. Внимательно изучите документацию Class.getResource и ClassLoader.getResource. Как только вы усвоите всю эту информацию, вы сможете разобраться в своей проблеме.
srcDir 'src/main/resources'
лишнее. Это уже исходный каталог по умолчанию для ресурсов в основном исходном наборе. Также обратите внимание, что srcDir
добавляет только исходный каталог, а не заменяет существующие.
Пусть x.txt
будет ресурсом, находящимся на листе вашего дерева ресурсов, а класс, из которого вы к нему получаете доступ, будет называться X
. Код, который я бы использовал: URL u = X.class.getResource("/main/it/uni/cs/name/progettofinaledatemplate/x.txt");
Теперь вы можете увидеть причину моего комментария о чрезмерном вложении.
@g00se, если ресурс находится в том же пакете в каталоге ресурсов, что и класс, из которого вы его загружаете, вы можете не указывать путь к пакету. Таким образом, наличие ресурсов в структуре пакета дает некоторую выгоду.
Это правда. Но этот шаблон, по крайней мере, «всегда» будет работать, поэтому я бы привел его в первую очередь.
Обратите внимание, что ClassLoader::getResource
принимает только абсолютные пути, но без ведущих /
. Это отличается от Class::getResource
. И обратите внимание, что каталог src/main/resources
никогда не будет частью этого пути (если только вы не делаете какие-то странные и нетрадиционные вещи). Считайте каталог resources
«корнем». Однако имейте в виду, что при поиске ресурсов действительно важен путь к классу/модулю, а не исходные каталоги. По умолчанию задача run
будет включать build/resources/main
в путь к классам для немодульных проектов.
Извините, не хотел быть загадочным. Чтобы уточнить, это конкретный путь, который я использую: URL url = this.getClass().getResource("it/uni/cs/name/progettofinaledatemplate/Tracciato3.txt");
Здесь используется Class::getResource
. В этом методе абсолютные пути обозначаются ведущим /
. Если нет начального /
, то путь определяется относительно местоположения класса (т. е. его пакета). Что будет, если поставить ведущий /
? Или что произойдет, если вы просто используете "Tracciato3.txt"
(при условии, что класс, возвращаемый getClass()
, находится в пакете it.uni.cs.name.progettofinaledatemplate
).
URL-адрес = this.getClass().getResource("it/uni/cs/name/progettofinaledatemplate/Tracciato3.txt"); Было бы нормально, если бы имя пакета this
было относительно правильным. Лично я считаю, что безопаснее и менее сомнительно использовать абсолютную форму, которую я уже дал.
Решение, которое работало с моим приложением:
Выслушав множество полезных советов, я удалил вложенность файлов ресурсов, учитывая имя файла «Tracciato3.txt» и X — класс, который я использовал, я переместил файл «Tracciato3.txt» из:
src/main/resources/it/uni/cs/name/progettofinaledatemplate/Tracciato3.txt
к
src/main/resources/Tracciato3.txt
теперь, если я использую
URL url = X.class.getClassLoader().getResource("Tracciato3.txt");
он не возвращает ноль, вместо этого он получает правильный URL-адрес.
У меня это сработало, поэтому я надеюсь, что это будет полезно
Пожалуйста, используйте предварительный просмотр, чтобы проверить форматирование сообщения перед его отправкой. Сейчас отредактировал, но раньше было нечитабельно.