getResourceAsStream возвращает ноль

183

Я загружаю текстовый файл из пакета в скомпилированный JAR-файл моего Java-проекта. Соответствующая структура каталогов выглядит следующим образом:

/src/initialization/Lifepaths.txt

Мой код загружает файл, вызывая, Class::getResourceAsStreamчтобы вернуть InputStream.

public class Lifepaths {
    public static void execute() {
        System.out.println(Lifepaths.class.getClass().
            getResourceAsStream("/initialization/Lifepaths.txt"));
    }

    private Lifepaths() {}

    //This is temporary; will eventually be called from outside
    public static void main(String[] args) {execute();}
}

Распечатка всегда будет печатать null, независимо от того, что я использую. Я не уверен, почему вышеупомянутое не будет работать, поэтому я также попытался:

  • "/src/initialization/Lifepaths.txt"
  • "initialization/Lifepaths.txt"
  • "Lifepaths.txt"

Ни одна из этих работ. Я уже прочитал множество вопросов по этой теме, но ни один из них не помог - обычно они просто говорят, чтобы загружать файлы, используя корневой путь, что я уже делаю. Это или просто загрузить файл из текущей директории (просто загрузить filename), что я тоже пробовал. Файл компилируется в JAR в соответствующем месте с соответствующим именем.

Как мне это решить?

Базилик Бурк
источник
3
Вы проверили , что он действительно находится в файле баночки? Вы проверили корпус файла?
Джон Скит
@JonSkeet Это действительно компилируется в файл JAR в соответствующем месте, и случай правильный.
1
@greedybuddha Хотя я не могу вызвать это из статического контекста, я могу вызвать его, используя Lifepaths.class. При этом, почему это getClassLoader()позволяет работать? (Кроме того, не стесняйтесь
Вы можете показать Lifepaths.getClass()? Нет такого статического метода, определенного в Object ...
Puce
1
Посмотрите на этот ответ и посмотрите, сможете ли вы заставить его работать, используя getResource(String). Кстати, у меня всегда были проблемы с тем, чтобы заставить кого-то из них работать в staticконтексте. Проблема в основном в том, что получаемый загрузчик классов предназначен для классов J2SE. Вам необходимо получить доступ к загрузчику классов контекста, который предназначен для самого приложения.
Эндрю Томпсон

Ответы:

159

Lifepaths.class.getClass().getResourceAsStream(...) загружает ресурсы, используя системный загрузчик классов, он явно не работает, потому что он не видит ваши файлы JAR

Lifepaths.class.getResourceAsStream(...) загружает ресурсы, используя тот же загрузчик классов, что и класс Lifepaths, и он должен иметь доступ к ресурсам в ваших JAR-файлах

hoaz
источник
129
Просто для добавления: при вызове getResourceAsStream (name) имя должно начинаться с «/». Я не уверен, нужно ли это, но у меня есть проблемы без этого.
Дэвид
3
Я трахаюсь с этим с 8 утра вчерашнего утра. Спас меня. Мне также нужна была косая черта, чтобы все заработало.
Кайл
4
Также имейте в виду, что желаемый источник может находиться за пределами иерархии пакетов. В этом случае вам придется использовать «../» на вашем пути, чтобы подняться на один уровень, а затем перейти к другой ветви пути, чтобы добраться до вашего ресурса.
Зон
3
@ Давид - я думаю, что это (ведущий '/') необходимо, иначе он ищет относительно пакета Lifepaths.class
Mz A
5
Просто, чтобы добавить некоторую информацию, вам нужно добавить /перед вашим путем, если ваш файл находится в другом каталоге; например initialization/Lifepaths.txt. Если путь к файлу такой же, как у класса yout (но в ресурсах, как у main dir), вы можете просто указать имя файла без такового /. Например, если ваш класс имеет следующий путь src/main/java/paths/Lifepaths.java, ваш файл должен иметь этот путь src/main/resources/paths/Lifepaths.txt.
Дуитц