Java OutputStream эквивалентен getClass(). GetClassLoader(). GetResourceAsStream()

Я пытаюсь сохранить изменения, внесенные в мои свойства приложения. Файл .properties находится в пакете resources, который отличается от пакета, который содержит мой пользовательский интерфейс и модель.

Я открыл пакет, используя:

this.getClass().getClassLoader().getResourceAsStream("resources/settings.properties")

Есть ли функциональный эквивалент этого, который позволяет мне сохранять изменения в классе свойств в том же файле .Properties?

Ответы

Ответ 1

Похоже, вы хотите сохранить пользовательские настройки. Подумайте об этом с помощью API Java Preferences.

Ответ 2

В общем, вы не можете вернуть материал обратно в ресурс, который вы получили от загрузчика классов:

  • Ресурсы загрузчика классов часто доступны только для чтения; т.е. хранятся в файлах только для чтения/только для чтения.

  • Если вы получили ресурс из JAR файла, файлы JAR не просто обновляются. (Чтобы "обновить", вам нужно извлечь старое содержимое JAR и создать новый JAR с обновленным содержимым. Все это связано со структурой ZIP файлов...)

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

Даже если вы можете обновить ресурс, полученный от загрузчика классов, это плохая идея/плохая практика.

  • Выполнение этого "загрязняет" чистую установку приложения с пользовательскими настройками. Помимо всего прочего, это означает, что установка не может использоваться совместно с другими пользователями (если только вы не обрабатываете настройки для нескольких пользователей...).

  • Есть проблемы с безопасностью, когда приложения установлены как доступные для записи, так что встроенные настройки могут быть обновлены. Подумайте о вирусах! Подумайте одного пользователя, который может склоняться к другим настройкам пользователя!

  • Существуют проблемы с администрированием с использованием пользовательских копий приложений. И если пользователь должен установить свою собственную копию приложения, есть и потенциальные проблемы с безопасностью.

Наконец, это НЕ означает, что системные администраторы (и образованные пользователи) ожидают, что программное обеспечение будет себя вести. Лучше всего использовать ожидаемые способы пользовательских настроек:

  • Для Java-ориентированного решения используйте API Java Preferences.

  • В качестве альтернативы вы можете записать файл свойств, содержащий настройки, соответствующие каталогу, доступному для ОС.

  • В Windows вы можете использовать API, специфичный для Windows, для хранения настроек в реестре Windows (yuck).

Ответ 3

в пакете 'resources', который отличается от пакета, который содержит мой интерфейс и модель.

Для этого вы должны использовать загрузчик классов.

ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
properties.load(classLoader.getResourceAsStream("resources/settings.properties"));

Есть ли функциональный эквивалент этого, который позволяет мне сохранять изменения в классе свойств в том же файле .Properties?

Для этого вам нужен Properties#store(), который может принимать либо OutputStream или Writer. Сначала вам нужно получить URL файла свойств и получить его URI, чтобы вы могли создать File для этого, который вы переносите в FileOutputStream.

URL url = classLoader.getResource("resources/settings.properties");
properties.store(new FileOutputStream(new File(url.toURI())), null);

Ответ 4

Когда вы завершаете свое приложение как файл JAR, ваш файл свойств будет одним (возможно сжатым) файлом внутри этого JAR, и было бы неплохо попытаться написать в ваш JAR.

getResourceAsStream() предназначен для открытия ресурсов для чтения, и они могут быть в любом месте пути к классам. Вы не можете писать на URL-адреса или внутри JAR, вы можете писать только в файлы, поэтому нет смысла давать вам тот же API для вывода.

Найдите себе каталог, в который вы можете писать, и напишите свои свойства там.

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

Ответ 5

В дополнение к Carl answer, если вы собираетесь часто читать и писать в этот файл и ожидать, что ваше приложение будет расширяться по охвату, подумайте, выполните один шаг (или несколько шагов) дальше и используйте файловую базу данных, например SQLite. Существует несколько оболочек JDBC для SQLite, которые позволят вам выйти за рамки основного поиска по ключевым словам, которые предоставляет интерфейс Java Properties.