Подтвердить что ты не робот

Загрузка файла getClass(). GetResource()

Я выполнил способ загрузки файла ресурсов с помощью getClass.getResource(path). Ниже приведен фрагмент кода:

String url = "Test.properties";

System.out.println("Before printing paths..");
System.out.println("Path2: "+ getClass().getResource(url).getPath());

FileInputStream inputStream = new FileInputStream(new File(getClass().getResource(url).toURI()));
i_propConfig.load(inputStream);
inputStream.close();

Я настроил его в eclipse с помощью иерархии (под источником есть папка SwingDemo. В SwingDemo есть мой java файл, а также файл ресурсов)...

  • ЦСИ
    • SwingDemo
      • CustomDialog.java
      • Test.properties

Когда я запускаю это на eclipse, все работает нормально. Но как только я пытаюсь запустить приложения из cmd, возникает исключение нулевого указателя.

Иерархия развертывания командной строки выглядит следующим образом:

Папка: D:\Work\Java Progrms\SwingDemo

Иерархия:

  • SwingDemo
    • CustomDialog.java
    • Test.properties

Прежде всего, я скомпилировал этот файл внутри папки SwingDemo из командной строки (javac CustomDialog.java). Затем я перехожу на один шаг обратно в папку Java Programs (как я уже упоминал об этом пакете внутри класса .java) и запускаю приложения, используя знаменитый

java SwingDemo.CustomDialog

Я использовал следующие шаги, когда ранее использовал новый FileInputStream ( "путь" ). После выполнения этого способа я получаю исключение нулевой указатель.

Я думаю, что getClass().getResource(url) не может загрузить файл из определенного каталога. Поэтому я поместил ресурс в тот же каталог, что и мой java файл. Он отлично работал в Eclipse. Но почему это дает ошибку, когда я запускаю из командной строки.

4b9b3361

Ответ 1

getClass().getResource() использует загрузчик классов для загрузки ресурса. Это означает, что ресурс должен находиться в загружаемом классе.

Когда вы делаете это с Eclipse, все, что вы помещаете в исходную папку, "скомпилировано" Eclipse:

  • .java файлы скомпилированы в файлы .class, которые идут в каталог bin (по умолчанию).
  • другие файлы копируются в каталог bin (соблюдая иерархию пакетов/папок)

При запуске программы с Eclipse каталог bin таким образом находится в пути к классам, и поскольку он содержит файл Test.properties, этот файл может быть загружен загрузчиком классов, используя getResource() или getResourceAsStream().

Если это не работает из командной строки, это потому, что файл не находится в пути к классам.

Обратите внимание, что вы НЕ должны делать

FileInputStream inputStream = new FileInputStream(new File(getClass().getResource(url).toURI()));

для загрузки ресурса. Потому что это может работать только в том случае, если файл загружен из файловой системы. Если вы упаковываете приложение в файл jar или загружаете классы по сети, это не сработает. Чтобы получить InputStream, просто используйте

getClass().getResourceAsStream("Test.properties")

И, наконец, как указывает документация,

Foo.class.getResourceAsStream("Test.properties")

загрузит файл Test.properties, расположенный в том же пакете, что и класс Foo.

Foo.class.getResourceAsStream("/com/foo/bar/Test.properties")

загрузит файл Test.properties, расположенный в пакете com.foo.bar.

Ответ 2

Лучший способ получить доступ к файлам из папки ресурсов внутри банки - использовать InputStream через getResourceAsStream. Если вам все еще нужен ресурс в качестве экземпляра файла, вы можете скопировать ресурс в виде потока во временный файл (временный файл будет удален при выходе из JVM):

public static File getResourceAsFile(String resourcePath) {
    try {
        InputStream in = ClassLoader.getSystemClassLoader().getResourceAsStream(resourcePath);
        if (in == null) {
            return null;
        }

        File tempFile = File.createTempFile(String.valueOf(in.hashCode()), ".tmp");
        tempFile.deleteOnExit();

        try (FileOutputStream out = new FileOutputStream(tempFile)) {
            //copy stream
            byte[] buffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = in.read(buffer)) != -1) {
                out.write(buffer, 0, bytesRead);
            }
        }
        return tempFile;
    } catch (IOException e) {
        e.printStackTrace();
        return null;
    }
}