(проект лаб ,будет правиться пол результатам сдачи лаб 5)
Лабораторная работа № 6 — «Файлы, потоки, NIO и кодировки»
Результат этой работы — данные Finance Tracker перестают исчезать после завершения процесса.
Основная реализация должна использовать современный Path/Files, но классический I/O также изучается через небольшой сравнительный фрагмент. Методы Files.newBufferedReader() и Files.readString() в современном API работают с текстом и позволяют явно задавать Charset; для многих текстовых методов Files стандартным значением является UTF-8.
Студент генерирует CSV:
id;date;type;amount;category;description 550e8400-e29b-41d4-a716-446655440000;2026-09-01;EXPENSE;750.00;FOOD;Обед ...
Для учебной работы фиксируется упрощённый формат: символ ; внутри значения запрещён. В отчёте студент обязан указать, что это не универсальный CSV-parser и что реальный CSV с экранированием и кавычками требует полноценного парсера.
Необходимо реализовать:
public interface TransactionFileRepository { List<Transaction> load(Path path) throws IOException; void save( Path path, List<Transaction> transactions ) throws IOException; }
Основная реализация:
try (BufferedReader reader = Files.newBufferedReader(path, StandardCharsets.UTF_8)) { ... }
Try-with-resources автоматически управляет ресурсами, реализующими AutoCloseable/Closeable, и является предпочтительным учебным способом демонстрации корректного закрытия потока.
Эксперимент «байты или символы». Один текстовый файл копируется через Reader/Writer, один бинарный файл — через InputStream/OutputStream. Студент объясняет, почему нельзя воспринимать произвольный PNG как текст.
Эксперимент с кодировкой. Создать UTF-8 файл:
Доход;Расход;Кофе;Счёт
а затем намеренно прочитать его другой кодировкой и описать причину искажения текста. После этого исправить программу так, чтобы charset указывался явно.
Работа с Path:
Path dataDir = Path.of("data");
Files.createDirectories(dataDir);
Path csv = dataDir.resolve("transactions.csv");
Студент выполняет:
проверку существования; создание каталога; запись; чтение; копирование; получение размера;
и сравнивает File с Path/Files концептуально.
Требование по ошибкам: IOException нельзя превращать в "Ошибка!" внутри repository. UI-слой должен получить причину, зарегистрировать её и решить, что показать пользователю.
Автопроверка: round-trip objects → CSV → objects; русские символы сохраняются; ресурс закрывается; несуществующий файл обрабатывается предсказуемо; каталог создаётся при необходимости.
Вопросы для углубления:
Байтовые и символьные потоки: в чем различия и
что выбрать?
Зачем используются
буферизированные потоки (Buffered*)?
Как
работают File/Paths/Files и чем подход NIO
отличается от классического I/O?
Что такое
кодировка и какие проблемы она вызывает при
чтении/записи текстов?
Как корректно
обрабатывать IOException?
