getResourceAsStream возвращает null

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

/src/initialization/Lifepaths.txt

Код, используемый для загрузки файла, следующий:

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"

Ни один из этих вариантов не работает. I've read numerous questions so far on the topic, but none of them have been helpful - usually, they just say to load files using the root path, which I'm already doing. Это, или просто загрузить файл из текущего каталога (просто load filename), что я'также пробовал. Файл компилируется в JAR в соответствующем месте с соответствующим именем.

Как мне решить эту проблему?

Комментарии к вопросу (8)
Решение

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

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

Комментарии (6)

Правила следующие:

  1. проверьте расположение файла, который вы хотите загрузить, внутри JAR (и таким образом убедитесь, что он действительно добавлен в JAR)
  2. используйте либо абсолютный путь: путь начинается в корне JAR
  3. использовать относительный путь: путь начинается с каталога пакета класса, который вы вызываете getResource/ getResoucreAsStream

И попробуйте:

Lifepaths.class.getResourceAsStream("/initialization/Lifepaths.txt")

вместо

Lifepaths.class.getClass().getResourceAsStream("/initialization/Lifepaths.txt")

(не уверен, что это имеет значение, но первый будет использовать правильный ClassLoader/ JAR, в то время как я не уверен во втором)

Комментарии (3)

Таким образом, существует несколько способов получить ресурс из jar, и каждый из них имеет немного отличающийся синтаксис, где путь должен быть указан по-разному.

Лучшее объяснение, которое я видел, это статья из JavaWorld. Я подытожу здесь, но если вы хотите узнать больше, вам следует ознакомиться со статьей.

Методы

  1. ClassLoader.getResourceAsStream().

Формат: "/"-разделенные имена; без ведущих "/" (все имена абсолютные).

Пример: this.getClass().getClassLoader().getResourceAsStream("some/pkg/resource.properties");.

  1. Class.getResourceAsStream().

Формат: "/"-разделенные имена; ведущее "/" указывает на абсолютные имена; все остальные имена являются относительными к классу'пакету

Пример: this.getClass().getResourceAsStream("/some/pkg/resource.properties");.

Комментарии (3)

Не используйте абсолютные пути, сделайте их относительными к директории 'resources' в вашем проекте. Быстрый и грязный код, который отображает содержимое файла MyTest.txt из каталога 'resources'.

@Test
public void testDefaultResource() {
    // can we see default resources
    BufferedInputStream result = (BufferedInputStream) 
         Config.class.getClassLoader().getResourceAsStream("MyTest.txt");
    byte [] b = new byte[256];
    int val = 0;
    String txt = null;
    do {
        try {
            val = result.read(b);
            if (val > 0) {
                txt += new String(b, 0, val);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } 
    } while (val > -1);
    System.out.println(txt);
}
Комментарии (0)

Вы можете попробовать это, чтобы получить поток я.е сначала нужно получить URL-адрес и затем открыть его как поток.

URL url = getClass().getResource("/initialization/Lifepaths.txt"); 
InputStream strm = url.openStream(); 

Я когда-то был подобный вопрос: https://stackoverflow.com/questions/16563622/reading-txt-file-from-jar-fails-but-reading-image-works/16564611#16564611

Комментарии (1)

Там, кажется, проблема с classloader, который вы используете. Используйте contextClassLoader для загрузки класса. Это независимо от того, является ли он в статическом/нестатический метод

Резьба.currentThread().getContextClassLoader().методаgetresourceasstream......

Комментарии (0)

Я оказался в подобной проблеме. Так как я с помощью Maven мне нужно обновить pom.xml включить что-то вроде этого:

   ...




            /src/main/resources


            ../src/main/resources



        ...

Обратите внимание на метки ресурса там, чтобы указать, где эта папка находится. Если у вас есть вложенные проекты (как я), то вы, возможно, захотите, чтобы получить ресурсы из других областей, а не только в модуле, в котором вы работаете. Это помогает уменьшить сохраняя тот же файл в каждой сделки РЕПО при использовании подобных данных конфигурации

Комментарии (0)

Убедитесь, что ваш каталог ресурсов (например, на "НИЦ", у) находится в вашем classpath (убедитесь, что он's для исходного каталога в свой путь сборки в Eclipse).

Убедитесь, что clazz загружается из главного загрузчика.

Затем для загрузки src/initialization/Lifepaths.txt используйте

clazz.getResourceAsStream("/initialization/Lifepaths.txt");

Почему: clazz.getResourcesAsStream(ФОО) ищет Foo из в пределах класса clazz, по отношению к жизни clazz каталог в. Ведущих и"/" и делает его загрузить из корня любой каталог в classpath clazz.

Если вы're в контейнер какой-то, как Tomcat или делаете что-то с загрузчиками классов напрямую, вы можете просто относитесь к своим затмение/командной строке путь к классу, как только загрузчиком классов.

Комментарии (0)

Дон'т знать, если помогают, но в моем случае у меня был свой ресурс в папке /src/ и получал эту ошибку. Затем я переместил картинку в папку bin и исправили проблему.

Комментарии (0)

Грубо говоря:

getClass().методу getresource (и"/", у) нить~=.currentThread().getContextClassLoader().методу getresource (и".&и")

Предположим, структура проекта, как следующее:

`` ├── ГРЦ │   ├── главная │   └── тест │ испытания └── │ ├── Ява │ │   └── ком │ │   └── на GitHub │ │   └── АБВ │ │   └── прое │ │   ├── MainTest.java │ │   └── TestBase.java │ └── ресурсов │ └── abcd.txt └── целевые тест-классы └── ├── сом └── abcd.txt

``

`` // в MainClass.java это.getClass.ГТ; и quot методу getresource(" в/то") -&;~/proj_dir/целевой/тест-классы/"по это.getClass.методу getresource (и".&и") -> и"~/proj_dir/целевой/тест-классы/ком/гитхаб/ской/прое/с" Нить.currentThread().getContextClassLoader().getResources (и".&и") -> и"~/proj_dir/целевой/тест-классы/"и Нить.currentThread().getContextClassLoader().getResources(" в/то") -> нуль

``

Комментарии (0)

если вы не используете Maven убедитесь, что ваша упаковка 'цветы' Не 'пом'.

jar
Комментарии (0)

Что работал для меня было, чтобы добавить файл в мой проект/ресурсы Java/src и потом использовать

this.getClass().getClassLoader().getResourceAsStream(myfile.txt);

Я не'т должны явным образом добавить этот файл в путь (при добавлении его в /ГРЦ это очевидно)

Комментарии (1)

JVM по умолчанию classloader-загрузчик будет использовать родитель-classloader загрузить ресурсы в первую очередь: .

Lifepaths.класс.getClass()'с загрузчиком это загрузчик загрузчика классов, поэтомуметодаgetresourceasstreamбудет искать только $переменной JAVA_HOME, независимо от пользователя при условииклассов`. Очевидно, Lifepaths.txt нет.

Lifepaths.class 'ы classloader является путь к классу системного загрузчика классов, так методаgetresourceasstream поиск пользовательских классов и Lifepaths.txt есть.

При использовании Ява.яз.Класс#методаgetresourceasstream(имя строки), имя которого не начинается с **'/'** будет добавлено имя пакета в качестве префикса. Если вы хотите избежать этого, пожалуйста, используяЯва.яз.Класслоадер#методаgetresourceasstream`. Например: Ява Загрузчиком загрузчик = нить.currentThread().getContextClassLoader(); Строки имя_ресурса = "и Lifepaths.тхт и"; ResourceStream класса InputStream = загрузчик.методаgetresourceasstream(имя_ресурса);

Комментарии (0)

@Emracool... я'd предлагает вам альтернативу. Поскольку вы, кажется, пытаюсь загрузить *.файл txt. Лучше использовать FileInputStream (), а затем getClass это раздражает ().getClassLoader().getresourceasstream (), как или getClass().getresourceasstream (), как. По крайней мере, ваш код будет выполняться правильно.

Комментарии (2)