Загрузка файла 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. Но почему это дает ошибку, когда я запускаю из командной строки.
Ответы
Ответ 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;
}
}