Java OutputStream эквивалентен getClass (). GetClassLoader (). GetResourceAsStream () - PullRequest
15 голосов
/ 09 января 2010

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

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

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

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

Ответы [ 5 ]

24 голосов
/ 09 января 2010

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

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

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

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

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

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

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

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

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

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

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

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

9 голосов
/ 09 января 2010

в пакете '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);
5 голосов
/ 09 января 2010

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

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

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

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

2 голосов
/ 09 января 2010

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

0 голосов
/ 09 января 2010

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

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