[Java] Чтение и запись в файлы, Paint с сохранением
ПРЕДУПРЕЖДЕНИЕ
В рамках всего этого задания не используйте русские буквы, используйте транслит для вашего имени и фамилии, например Kolya.
Напоминание: чтение из консоли
Как было рассказано ранее для чтения из консоли вы можете воспользоваться Scanner
.
Пример для напоминания:
Scanner scanner = new Scanner(System.in); // Сканер позволит считывать числа или слова (разбитые по пробелу) из System.in, т.е. из консоли
System.out.println("Введите число: ");
int x = scanner.nextInt();
System.out.println("Введенное число умноженное на два: " + (x * 2));
System.out.println("Введите ваше имя и фамилию через пробел: ");
String name = scanner.next();
String surname = scanner.next();
System.out.println("Введенное имя: " + name + ", фамилия: " + surname);
Если вы что-то из этого забыли - обратитесь к старой статье.
Задание 1.1
Убедитесь что этот код работает. Добавьте в него считывание вещественного числа и выведите в консоль это число поделенное на два. Добавьте к имени и фамилии считывание отчества.
Чтение из файла
Единственное отличие от чтения из консоли - сканер конструируется не от System.in
(т.е. консоли), а от объекта представляющего файл:
Scanner scanner = new Scanner(new File("C:\\path\\to\\file.txt"));
// Дальнейшая работа со сканером не отличается от предыдущего случая чтения из консоли
Обратите внимание что даже после импортирования класса File
- вызов конструктора подсвечивается красным - Unhandled exception: java.io.FileNotFoundException
. Это то же что было и с Thread.sleep(10)
- только понятнее:
При создании объекта класса File
возможна исключительная ситуация - файл может быть не найден (например из-за неправильно указанного пути), в таком случае вызов конструктора кинет ошибку, которую нужно либо обработать, либо кинуть еще дальше. Пока что давайте просто кинем ее еще дальше - поставьте каретку ввода на конструктор new File
, нажмите Alt+Enter
и выберите Add exception to method signature
.
ПРЕДУПРЕЖДЕНИЕ
В рамках всего этого задания не используйте русские буквы, используйте транслит для вашего имени и фамилии, например Kolya.
Задание 1.2
Создайте файл на диске состоящий из ввода в консоль для предыдущего задания (т.е. целое число, вещественное число и ФИО). Считайте все данные из него так же как в предыдущем задании (единственное отличие - Scanner
конструируется теперь не от консоли, а от файла).
Альтернативный вариант
Если же вам интересно как можно обработать ошибку иначе - вы можете “поймать и обработать” ошибку, обернув try-catch
конструкцией:
try {
File file = new File("C:\\path\\to\\file.txt");
Scanner scanner = new Scanner(file);
// Дальнейшая работа со сканером не отличается от предыдущего случая чтения из консоли
} catch (FileNotFoundException e) {
System.out.println("Файл не найден!"); // Сообщаем пользователю в доступной форме что произошло (в соответствии с типом ошибки - см. предыдущую строчку)
e.printStackTrace(); // Выводим подробную информацию об ошибке
}
Чтение из произвольного файла
Но что если хочется читать из файла, который выберет пользователь в момент запуска приложения?
Подумайте хотя бы минуту, как бы вы могли это реализовать?
Тут какое-то количество текста чтобы вы не смогли увидеть решение сразу случайно краем своего внимательного глаза. Если же вы читаете это не подумав и минуты - то где-то сейчас грустит один Коля, не надо так. Если же вы читаете это подумав, то возможно вы догадались, что можно попросить пользователя ввести в консоль путь к файлу, считать этот путь в строчку (создав еще один сканер - от консоли), и передать эту строчку в конструктор File
заместо константного пути.
Задание 1.3
Сделайте так. Т.е. возьмите результат предыдущего задания, и сначала заправшивайте у пользователя путь к файлу (он должен его ввести без двойных слешей), а конструируйте файл от этого пути (передав считанный путь в конструктор). Обратите внимание что это не работает если путь включает пробел, т.к. сканер разбивает введенные данные на кусочки по пробелам.
Но есть и еще один вариант достичь этого - попросить пользователя выбрать файл через диалоговое окошко выбора файла.
Ниже пример показа диалогового окошка, и вывода в консоль пути к выбранному файлу.
FileDialog dialog = new FileDialog((Frame) null);
dialog.setVisible(true); // Показали окно и данный вызов не завершиться, пока пользователь не выберет файл или не закроет окно
String directory = dialog.getDirectory(); // Узнали папку выбранную пользователем (может быть null)
String filename = dialog.getFile(); // Узнали файл выбранный пользователем (может быть null)
dialog.dispose(); // Сказали что все ресурсы связанные с диалоговым окном можно освободить
if (directory == null || filename == null) {
System.out.println("Файл не выбран!");
return;
}
String path = directory + filename; // Сложив папку и название файла - получает полный путь к файлу
System.out.println("Выбранный файл: " + path);
Задание 1.4
В программе получившейся в прошлом задании замените считывание пути к файлу из консоли на запрашивание файла через диалоговое окно с последующим считыванием из этого файла чисел и ФИО.
Запись в файл
Напоминание - печатать символы в консоль можно так:
int x = 10;
System.out.println("сИмВоЛы и ЧиСлО: " + x);
Но какого типа объект System.out
? В IDEA можно это выяснить напечатав System.out
и нажав Ctrl+Space
. Попробуйте сделать это сами. Заметьте что справа от out
в выпадающем списке будет написан тип - PrintStream
.
Чтобы создать аналогичный объект для записи в файл - можно воспользоваться классом PrintWriter
(почти как PrintStream
, только он печатает не в консоль, т.е. не в Stream=поток=консоль, а во что угодно):
PrintWriter out = new PrintWriter(file);
out.println("test");
Задание 2.1
Создайте объект File file
с путем к файлу которого пока что нет. Создайте PrintWriter
от этого файла. Напечатайте в этот файл строчку и значение переменной int testIntVariable = 30;
.
При выполнении этого задания вы скорее-всего заметили что файл появляется, но пустой. Почему?
Потому что Java
не сразу пишет в файл, а лишь тогда когда PrintWriter
будет закрыт через вызов метода close()
.
Задание 2.2
Добавьте к предыдущему заданию в конце программы вызов out.close()
. Проверьте что теперь ваша программа пишет в файл строчку и число.
Собираем все это вместе в рисовальщик точек с сохранением холста
Задание 3.1
Сделайте простой Paint: например пусть на вашей MyPanel
можно будет рисовать только точки при нажатии кнопки мышки.
Задание 3.2
Сделайте так, чтобы при запуске ваш Paint считывал заранее записанные в каком-нибудь файле точки. Как представить точки в текстовом виде решите сами - что-нибудь вроде целочисленных координат по оси абсцисс и ординат через пробел вполне подойдет.
Задание 3.3
Добавьте кнопку “Сохранить”, которая будет записывать нарисованные точки в этот файл (в т.ч. точки считанные из файла при запуске приложения).
Задание 3.4
Пусть ваш Paint при запуске предлагает диалоговое окошко выбора файла из которого нужно загрузить точки. В случае если файл не выбран (например диалоговое окно было закрыто) - Paint должен запускаться с чистым холстом без точек.
Задание 3.5
Пусть ваш Paint при сохранении так же предлагает диалоговое окошко выбора файла для сохранения точек.