Загрузка файлов с помощью ClassLoader
Эта проблема давно искала меня. Мне нужно загрузить пару файлов в моем приложении java, и единственный способ, которым я работал, выглядит так:
URL hsURL;
if(System.getProperty("os.name").toLowerCase().contains("windows")) {
hsURL = new URL("file:/" + System.getProperty("user.dir") + "/helpsets/helpset.hs");
}
else {
hsURL = new URL("file://" + System.getProperty("user.dir") + "/helpsets/helpset.hs");
}
Но это уродливо и ужасно. Некоторое время я думал, что это работает:
hsURL = ClassLoader.getSystemResource("helpsets/helpset.hs");
Но это уже не работает по какой-то причине (я, должно быть, что-то изменил и не заметил. Он возвращает null.
Должен ли я использовать getResource() вместо getSystemResource() (если это так, почему getSystemResource() статический, но не getResource())?
Я использую eclipse, и я попытался включить папку в путь сборки (classpath), и не включая ее, это, похоже, не имеет значения.
Ответы
Ответ 1
getSystemResource
является статическим, потому что он будет использовать системный загрузчик классов, который доступен статически. (ClassLoader.getSystemClassLoader
)
Если ваш ресурс доступен в пути к классам, я бы предложил использовать ClassLoader.getResource()
или Class.getResource
из соответствующего класса, например.
Foo.class.getResource("/helpsets/helpset.hs");
(ClassLoader.getResource
является "абсолютным"; Class.getResource
относится к пакету класса, если вы не префикс его с помощью '/'.)
Если это не работает, сообщите, как ваше приложение настроено с точки зрения пути к классам и где находится ваш файл.
EDIT: я обычно считаю URL менее полезным, чем InputStream
, поэтому я использую getResourceAsStream
вместо getResource
. YMMV
Ответ 2
Вы упомянули здесь несколько разных вещей, поэтому отпустите их.
1) Создание URL-адреса "file:" на основе "user.dir"
Свойство user.dir относится к текущему рабочему каталогу - где бы пользователь ни находился, когда он начал приложение. Скорее всего, файлы, написанные здесь, будут исчезать между двумя прогонами (потому что пользователь может запускаться из другого каталога).
Свойство "user.home" относится к домашнему каталогу пользователя, который должен оставаться неизменным между прогонами.
В любом случае, используйте объект File для открытия файлов, не обманывайте себя при создании URL-адреса "file:". Вы не получаете никакой пользы, и, как вы можете видеть, вам нужно написать беспорядочный код для доступа к нему.
2) Получение ресурса через загрузчик классов
Это предназначено для извлечения файлов, которые упакованы вместе с вашим приложением - файлы только для чтения. Как вы видели, существует несколько вариантов. Я предпочитаю использовать следующее, потому что я предполагаю, что класс захочет загрузить файл, который упакован вместе с ним.
InputStream in = this.getClass().getClassLoader().getResourceAsStream(fileName);