- Отзывы
- О нас
- CS50
Хэлп! При нажатии на кнопку «Получение списка доступных задач», выдает ошибку «Ошибка при создании файла properties.». В чем проблема?
Этот веб-сайт использует данные cookie, чтобы настроить персонально под вас работу сервиса. Используя веб-сайт, вы даете согласие на применение данных cookie. Больше подробностей — в нашем Пользовательском соглашении.
JavaRush — это интерактивный онлайн-курс по изучению Java-программирования c нуля. Он содержит 1200 практических задач с проверкой решения в один клик, необходимый минимум теории по основам Java и мотивирующие фишки, которые помогут пройти курс до конца: игры, опросы, интересные проекты и статьи об эффективном обучении и карьере Java‑девелопера.
Подписывайтесь
Property файлы присутствуют практически в каждом проекте, и сейчас я вам покажу простой пример их использования, а также расскажу, зачем они и где используются.
Шаг 0. Создание проекта
Начнем с того что создадим простой Maven проект, указав название и имя пакета:
Структура, которая получится в конце проекта довольно таки простая.
Как видите у нас только два файла, первый – Main.java, а второй – config.properties.
Шаг 2. Добавляем конфигурационные данные в проперти файл
Проперти файлы либо файлы свойств – предназначены, для того чтобы хранить в них какие-то статические данные необходимые проект, например логин и пароль к БД.
Давайте добавим в наш config.properties логин и пароль (это любые данные, для того чтобы продемонстрировать работу с property файлами).
Содержимое config.properties:
db.host = http://localhost:8888/mydb db.login = root db.password = dbroot
Как видите, данные представлены в виде {ключ} = {значение}, где
{ключ} – это уникальное имя, по которому можно получить доступ к значению, хранимому под этим ключом.
{значение} – это текст, либо число, которое вам необходимо для выполнения определённой логики в вашей программе.
Шаг 3. Получаем Property данные
Как можно видеть в структуре проекта выше, там есть класс Main.java давайте его создадим и напишем в нем следующее:
package com.devcolibir.prop; import java.io.*; import java.util.Properties; public class Main { public static void main(String[] args) { FileInputStream fis; Properties property = new Properties(); try { fis = new FileInputStream("src/main/resources/config.properties"); property.load(fis); String host = property.getProperty("db.host"); String login = property.getProperty("db.login"); String password = property.getProperty("db.password"); System.out.println("HOST: " + host + ", LOGIN: " + login + ", PASSWORD: " + password); } catch (IOException e) { System.err.println("ОШИБКА: Файл свойств отсуствует!"); } } }
Обращаясь к property.getProperty({ключ}) – вы получаете его значение.
Вот такой краткий, но думаю познавательный урок.
- None Found
Вы достигли нового уровня
— Привет, Амиго! Сегодня мы познакомимся с еще одной интересной темой. А именно: сохранением и загрузкой (восстановлением) объектов. Допустим у нас есть класс Cat:
Код |
---|
class Cat { public String name; public int age; public int weight; } |
И мы хотим добавить в него удобный механизм сохранения в файл и загрузки из файла.
Вот как это можно сделать:
Код |
---|
class Cat { public String name; public int age; public int weight; public void save(OutputStream outputStream) throws Exception public void load(InputStream inputStream) throws Exception |
— О! Это же очень просто. Мы просто печатаем значения всех аргументов, по одному в каждой строчке. А при загрузке читаем их в том же порядке. Отличное решение.
— Спасибо, Амиго. А можешь написать, как будут выглядеть методы save и load у такой группы классов:
Код |
---|
class Cat { public String name; public int age; public int weight; } class Dog { public String name; public int age; } class Human { public Cat cat; public Dog dog; } |
У тебя есть объект человек, и он может иметь одну собаку и одного кота.
— У меня есть решение:
Код |
---|
class Cat { public String name; public int age; public int weight; public void save(OutputStream outputStream) throws Exception public void load(InputStream inputStream) throws Exception |
class Dog { public String name; public int age; public void save(OutputStream outputStream) throws Exception public void load(InputStream inputStream) throws Exception |
class Human { public Cat cat; public Dog dog; public void save(OutputStream outputStream) throws Exception public void load(InputStream inputStream) throws Exception |
— Очень хорошее решение. Но что будет, если у человека нет кота, а есть только собака?
Где проверки на null?
— Сейчас исправлю:
Код |
---|
class Human { public Cat cat; public Dog dog; public void save(OutputStream outputStream) throws Exception public void load(InputStream inputStream) throws Exception |
— Все равно не очень верно. У тебя две ошибки:
1) Если у человека нет ни кота, ни собаки, они все равно будут созданы, при вызове метода load
2) Если мы сохраним только собаку, то ее данные будут прочитаны котом при загрузке.
— А что же делать?
— Мы не можем пропускать запись переменных, иначе это вызовет сбой при чтении. Но нужно сделать так, чтобы переменные, чье значение было null при сохранении и после загрузки, получали null. Вот мой вариант:
Код |
---|
class Human { public Cat cat; public Dog dog; public void save(OutputStream outputStream) throws Exception String isCatPresent = cat != null ? «yes» : «no»; if (cat!=null) String isDogPresent = dog != null ? «yes» : «no»; if (dog != null) public void load(InputStream inputStream) throws Exception String isCatPresent = reader.readLine(); String isDogPresent = reader.readLine(); |
— Да, мне нравится такое решение.
— Да, что-то в нем есть.
— Привет, Амиго!
Задачи |
---|
1. Читаем и пишем в файл: Human
Реализуйте логику записи в файл и чтения из файла для класса Human |
2. Читаем и пишем в файл: JavaRush
Реализуйте логику записи в файл и чтения из файла для класса JavaRush |
3. Знакомство с properties
В методе fillInPropertiesMap считайте имя файла с консоли и заполните карту properties данными из файла. |
4. Читаем и пишем в файл статики
Реализуйте логику записи в файл и чтения из файла для класса ClassWithStatic |
5. И еще раз о синхронизации
Разберитесь почему не работает метод main() |
— Помнишь, мы сегодня разбирали сохранение объектов в файл и чтение из файла?
— Да, только мы сохраняли в поток вывода, а читали из потока ввода.
— Молодец, Амиго. Приятно слышать, что ты замечаешь такие мелочи. А ты бы смог дописать код, чтобы было сохранение в файл и чтение из файла?
— А что там писать?! Объявил FileInputStream и FileOutputStream и передавай их в методы save & load. Тут уже ничего не перепутаешь — все просто.
— Рада за тебя. Итак, новая тема – сериализация.
Сериализация – это практически то же самое, что мы с тобой только что делали, только гораздо круче и встроено прямо в Java-машину. Java-машина умеет сохранять и загружать свои объекты. Для этого ей даже не требуются методы save & load: все объекты хранятся внутри Java-машины, и она имеет к ним полный доступ.
Мы просто берем объект и сохраняем его в поток/читаем из потока:
Код |
---|
public static void main(String[] args) throws Exception { Cat cat = new Cat(); //save cat to file //load cat from file Cat newCat = (Cat)object; |
— И все?
— Да. Там очень большой и сложный механизм сериализации, который поддерживает сохранение в поток и чтение из потока почти всех типов данных.
— Почти всех, это значит не всех?
— Да, дело в том, что не все объекты по своей сути можно сохранить. Некоторые объекты не хранят все свои данные в себе, а лишь ссылаются на другие объекты и/или источники данных. Например, консоль (System.in), поток ввода (InputStream), или что-нибудь еще.
Поэтому разработчики Java придумали специальный интерфейс-маркер – Serializable. Его называют маркером, т.к. он не содержит никаких данных и методов. Он используется только для того, чтобы «помечать» (маркировать) классы. Если мы считаем, что наш класс хранит в себе все свои данные, тогда мы можем пометить его этим маркером – написать implements Serializable.
Пример «кота» с поддержкой сериализации:
Код |
---|
class Cat implements Serializable { public String name; public int age; public int weight; } |
Когда мы пытаемся сериализовать (сохранить) какой-нибудь объект, Java-машина проверяет – поддерживает ли он сериализацию: реализует ли он интерфейс Serializable? Если да, то сохраняет объект, если нет – выкидывает исключение о невозможности сериализации.
Тут нужно понимать, что сериализуемый объект должен состоять тоже только из сериализуемых объектов.
— Ну, этого и следовало ожидать. Нельзя же сохранить целое, не сохранив какие-то его части.
— Именно так.
— А как же типы int, String, ArrayList?
— Они все поддерживают сериализацию, на этот счет разработчики Java специально позаботились. Тут проблем быть не должно.
Более того, при сериализации объекта сохраняется его тип. Теперь ты можешь в переменную класса с типом Object сохранить ссылку на объект Cat, и все это отлично сериализуется и десериализуется.
— Десериализуется?
— Десериализация – так называют процесс, обратный сериализации – чтение и восстановление объекта из потока/файла.
— Тогда вопросов больше нет.
— Привет, Амиго!
Задачи |
---|
1. Как сериализовать?
Сделайте так, чтобы сериализация класса Human была возможной |
2. Как сериализовать JavaRush?
Сделайте так, чтобы сериализация класса JavaRush была возможной |
3. Как сериализовать Singleton?
Два десериализованных объекта singleton и singleton1 имеют разные ссылки в памяти, а должны иметь одинаковые. |
4. Как сериализовать static?
Сделайте так, чтобы сериализация класса ClassWithStatic была возможной |
5. Как сериализовать что-то свое?
Сделайте так, чтобы сериализация класса Object была возможной |
— Привет, Амиго! Хотела тебе порассказывать одно маленькое дополнение к сериализации.
Допустим наш класс содержит ссылку на какой-нибудь InputStream, тогда его нельзя сериализовать, ведь так?
— Да. Ты же сама говорила, что потоки сериализовать нельзя. А сериализовать объект, у которого есть несериализуемые данные – тоже нельзя.
— Да. Именно так. Но что, если класс хранит данные, которые не играют значащей роли в его состоянии, но мешают считаться ему сериализуемым классом? Мало ли что класс может у себя хранить ненужного. Возможно, он может выбросить эти данные в любой момент или даже так и делает постоянно.
Для таких случаев разработчики Java придумали специальное слово – transient. Его можно написать перед переменной класса и она будет не учитываться при сериализации. Ее состояние не будет ни сохраняться, ни восстанавливаться. Как будто и нет ее вовсе. Как раз для таких ситуаций, как мы только что рассмотрели.
Помнишь кеширование и модификатор volatile? Нет правил без исключений.
Вот тебе один примерчик такого счастья:
Пример «кота» с невидимой для сериализации переменной — in:
Код |
---|
class Cat implements Serializable { public String name; public int age; public int weight; transient public InputStream in = System.in; |
— Привет, Амиго! Хотел бы немного дополнить то, что рассказала тебе Элли.
Иногда бывает нужно управлять процессом сериализации. Вот одни из причин:
1) Объект не готов к сериализации: его нынешнее внутреннее состояние в процессе изменения.
2) Объект содержит несериализуемые объекты, но может перевести их в удобную для сериализации форму: сохранить в массив байт или что-нибудь еще.
3) Объект хочет десериализовать все свои данные, как одно целое и/или зашифровать их перед сериализацией.
Причин выполнить сериализацию в ручном режиме может быть множество. Но не хотелось бы лишаться всех тех преимуществ, которые дает стандартная сериализация. Ведь наш объект могут использовать другие объекты. И они тоже не смогут сериализоваться, если наш объект откажется от поддержки сериализации.
На этот случай тоже есть решение – интерфейс Externalizable. Спасибо дальновидным разработчикам Java. Достаточно заменить интерфейс Serializable на интерфейс Externalizable, и ваш класс сможет управлять процессом сериализации в ручном режиме.
Дело в том, что интерфейс Externalizable, в отличие от Serializable, содержит два метода, которые вызываются Java-машиной при сериализации объекта. Вот как это выглядит:
Код |
---|
class Cat implements Externalizable { public String name; public int age; public int weight; public void writeExternal(ObjectOutput out) public void readExternal(ObjectInput in) |
Ничего не напоминает?
— Ух ты! Именно так мы пробовали сохранять объекты до «изобретения» сериализации.
— Да, теперь все просто: если устраивает стандартная сериализация – просто наследуем наш класс от интерфейса Serializable. Если не устраивает – наследуем от Externalizable и пишем код для сохранения/загрузки объекта нашего класса.
— А класс, помеченный Externalizable, считается сериализуемым? Мы можем «безопасно» хранить на него ссылки в наших сериализуемых классах?
— Да. Если класс реализует интерфейс Serializable или Externalizable, он считается сериализуемым.
— Отличное решение. Мне нравится.
— Рад это слышать. Но это еще не всё… Спроси лучше профессора Ханса о всяких нюансах. Они тут точно есть. Он хотел тебе дать что-то почитать.
— Привет, Амиго!
Задачи |
---|
1. Externalizable для апартаментов
Реализуйте интерфейс Externalizable для класса Apartment |
2. OutputToConsole
Класс OutputToConsole должен сериализоваться с помощью интерфейса Externalizable. |
3. Externalizable Person
Класс Person должен сериализоваться с помощью интерфейса Externalizable. |
4. Serializable Solution
Сериализуйте класс Solution. |
5. Переопределение сериализации
Сделайте так, чтобы после десериализации нить runner продолжила работать. Hint/Подсказка: Конструктор не вызывается при сериализации, только инициализируются все поля. |
— А если ты хочешь расширить или углубить свои знания по сериализации. Или, не дай бог, что-нибудь не понял, то для тебя у меня есть замечательные лекции.
Ссылка на сериализацию
— Привет, Амиго! Устал? Ничего, тяжело в учении – легко в бою. Давай посмотрим хорошее видео.
Оригинал видео на YouTube
— Привет, Амиго! Что-то ты расслабился! Вот твои задания. Если вдруг возникнут трудности, то обращайся к коллегам, они точно помогут.
Дополнительные задания для выполнения в Intellij Idea |
---|
1. Минимум изменений
Используя минимум изменений кода сделайте так, чтобы сериализация класса C стала возможной. |
2. Десериализация
На вход подается поток, в который записан сериализованный объект класса A либо класса B. |
3. Найти ошибки
Почему-то при сериализации/десериализации объекта класса B возникают ошибки. |
4. Исправить ошибку
После десериализации объекта класса Solution обнаружили, что данных в словаре [m] нет |
5. Сериализуйте Person
Сериализуйте класс Person стандартным способом. |
6. Запрет сериализации
Запретите сериализацию класса SubSolution используя NotSerializableException. |
7. Переопределение сериализации в потоке
Сериализация/десериализация Solution не работает. |
8. Правильный вывод
Расставить обращение к методам суперкласса и модификаторы доступа так, чтобы вывод на экран был следующим: C class, method2 Количество изменений модификаторов доступа и вызовов методов должно быть минимально |
9. Знакомство с графами
Прочитать в дополнительных материалах о сериализации графов. |
— Ты уже всё сделал? Вот тебе ещё и бонусные задания повышенной сложности:
1. Алгоритмы-числаЗадача: Число S состоит из M чисел, например, S=370 и M(количество цифр)=3 Реализовать логику метода getNumbers, который должен среди натуральных чисел меньше N (long) находить все числа, удовлетворяющие следующему критерию: число S равно сумме его цифр, возведенных в M степень getNumbers должен возвращать все такие числа в порядке возрастания Пример искомого числа: На выполнение дается 10 секунд и 50 МБ памяти. |
2. Алгоритмы-прямоугольникиЗадача: 1. Дан двумерный массив N*N, который содержит несколько прямоугольников. 2. Различные прямоугольники не соприкасаются и не накладываются. 3. Внутри прямоугольник весь заполнен 1. 4. В массиве: 4.1) a[i, j] = 1, если элемент (i, j) принадлежит какому-либо прямоугольнику 4.2) a[i, j] = 0, в противном случае 5. getRectangleCount должен возвращать количество прямоугольников. 6. Метод main не участвует в тестировании |
3. КроссвордЗадача: 1. Дан двумерный массив, который содержит буквы английского алфавита в нижнем регистре. 2. Метод detectAllWords должен найти все слова из words в массиве crossword. 3. Элемент(startX, startY) должен соответствовать первой букве слова, элемент(endX, endY) — последней. text — это само слово, располагается между начальным и конечным элементами 4. Все слова есть в массиве. 5. Слова могут быть расположены горизонтально, вертикально и по диагонали как в нормальном, так и в обратном порядке. 6. Метод main не участвует в тестировании |
4. Свой списокЗадача: Посмотреть, как реализован LinkedList. Элементы следуют так: 1->2->3->4 и так 4->3->2->1 По образу и подобию создать Solution. Элементы должны следовать так: 1->3->7->15 ->8... ->4->9 ->10 2->5->11 ->12 ->6->13 ->14 Во внутренней реализации элементы должны добавляться по 2 на каждый уровень |
не выходит найти .properties файл. Опробывл всё, и указывать полный пусть, аля java.info и прочее, Всё равно не выходит
Исключение:
Exception in thread «main» java.lang.ExceptionInInitializerError
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:264)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:122)
Caused by: java.util.MissingResourceException: Can’t find bundle for base name info.properties, locale ru_RU
at java.util.ResourceBundle.throwMissingResourceException(ResourceBundle.java:1564)
at java.util.ResourceBundle.getBundleImpl(ResourceBundle.java:1387)
at java.util.ResourceBundle.getBundle(ResourceBundle.java:773)
at One.(One.java:8)
… 3 more
Доброго времени суток. Есть проблема с чтением файла Properties
, содержащего русские буквы. Слово Нахабино считывается как ???°???°?±??????. Вот код:
Properties mProperties = new Properties();
mProperties.load(new FileInputStream(desktop + "pr.properties"));
System.out.println(mProperties.getProperty("setA"));
Пробовал при помощи Notepad++ менять кодировку файла на Asii, UTF-8, UTF-8 без BOM, UCS2, и ещё несколько. Результат — в одной кодировке вопросики и плюсики, в другой квадратики и кружочки и т.д. Помогите исправить ошибку.
задан 27 дек 2016 в 12:32
2
Согласно стандарту, .properties
файлы содержат текст в кодировке ISO 8859-1. Это создает определенные трудности при работе с кириллическими символами, т.к. все тот же стандарт предписывает кодировать их как escape-последовательности Unicode. Что выглядит не очень читабельно:
some.key=u0417u043Du0430u0447u0435u043Du0438u0435
К счастью, IDE имеют функциональность (встроенную или через плагины) для прозрачного преобразования кодировки, называемую native-to-ascii conversion. Благодаря этому, вы можете при редактировании видеть в IDE понятный текст:
some.key=Значение
который будет фактически преобразован в текст из предыдущего примера.
При загрузке файла через класс Properties
вы будете иметь дело уже с java-строками в Unicode и кириллица там будет такая, как вы ожидаете.
ответ дан 27 дек 2016 в 13:13
Nofate♦Nofate
34.3k15 золотых знаков65 серебряных знаков93 бронзовых знака
6
Я создал вот такой прекрасный класс:
private class MyProperties {
private File mFile;
private ArrayList<String> keys = new ArrayList<String>(), values = new ArrayList<String>();
MyProperties() throws Throwable {
// FileInputStream fis...
// загружаем в массивы keys и values значения
}
synchronized ArrayList<String> keySet() {
return this.keys;
}
synchronized String getProperty(String key, String defaultValue) {
for (int i1 = 0; i1 < this.keys.size(); i1++) {
if (this.keys.get(i1).equals(key)) {
return this.values.get(i1);
}
}
return defaultValue;
}
synchronized void setProperty(String key, String value) throws Throwable {
this.values.set(this.keys.indexOf(key), value);
DataOutputStream out = new DataOutputStream(new FileOutputStream(this.mFile));
for (int i1 = 0; i1 < this.keys.size(); i1++) {
out.writeBytes(this.keys.get(i1) + "=" + this.values.get(i1));
}
out.flush();
out.close();
}
}
жить с ним просто чудо. Не надо теперь париться по поводу каких-то кодировок и русских букв. Читает всё подряд.
ответ дан 27 дек 2016 в 14:45
nicknick
2,5005 золотых знаков28 серебряных знаков55 бронзовых знаков
7