Загрузка файла методом 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
- SwingDemo
Когда я запускаю это на затмении, все работает нормально. Но как только я пытаюсь запустить приложения из строки cmd, возникает исключение нулевого указателя..
Иерархия развертывания командной строки выглядит следующим образом:
Папка: D:\Work\Java Progrms\SwingDemo
Иерархия:
- SwingDemo
- CustomDialog.java
- Test.properties
Прежде всего я скомпилировал этот файл внутри SwingDemo
папка из командной строки (javac CustomDialog.java
). Затем я возвращаюсь на шаг назад в папку "Программы Java" (как я уже упоминал о пакете внутри класса.java) и запускаю приложения, используя знаменитую
java SwingDemo.CustomDialog
Я имел обыкновение следовать аналогичным шагам, когда я использовал новый FileInputStream("путь") ранее. После этого я получаю исключение нулевого указателя..
Я думаю getClass().getResource(url)
не может загрузить файл из определенного каталога. Вот почему я поместил ресурс в тот же каталог, что и мой файл Java. В Eclipse все работало нормально. Но почему это дает ошибку, когда я запускаю из командной строки.
2 ответа
getClass().getResource()
использует загрузчик классов для загрузки ресурса. Это означает, что ресурс должен быть в пути к классу для загрузки.
При работе с Eclipse все, что вы помещаете в исходную папку, "компилируется" Eclipse:
- Файлы.java компилируются в файлы.class, которые попадают в каталог bin (по умолчанию)
- другие файлы копируются в каталог bin (с учетом найма пакета / папки)
При запуске программы с Eclipse каталог bin находится в classpath, и, поскольку он содержит файл 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
,
Лучший способ получить доступ к файлам из папки ресурсов внутри jar - это использовать 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;
}
}