Files
aston-team-project/docs/tasks/CsvStudentIO.md
T

9.6 KiB

Техническое задание: чтение и дозапись Student в CSV

Задача

Реализовать два независимых класса для работы с объектами Student в формате CSV:

  • StudentCsvWriter — дозапись студентов в файл;
  • StudentCsvReader — последовательное чтение студентов из файла.

Для работы с форматом CSV использовать готовую библиотеку для работы с CSV. Самостоятельно реализовывать парсинг CSV запрещено.

Оба класса должны принимать абсолютный путь к файлу.

Исключения Student и StudentBuilder не обрабатывать.


Формат CSV-файла

Первая строка файла должна содержать заголовок:

groupNumber,averageGrade,recordBookNumber

Каждая следующая строка содержит данные одного студента:

groupNumber,averageGrade,recordBookNumber

Пример:

groupNumber,averageGrade,recordBookNumber
A12,4.5,10001
B07,3.8,10002
C25,4.9,10003

Для формирования и чтения CSV использовать стандартную библиотеку для работы с форматом CSV.


StudentCsvWriter

Назначение

Дозаписывать одного студента в указанный CSV-файл.

Контракт

Конструктор:

public StudentCsvWriter(String absoluteFilePath)

Метод:

public void write(Student student) throws IOException

Требования

  1. Метод принимает одного Student.
  2. Запись выполняется в режиме добавления.
  3. Существующие записи не изменяются.
  4. Если файл существует, заголовок повторно не записывается.
  5. Если файл не существует, необходимо создать файл.
  6. При создании нового файла имя должно соответствовать формату:
students-yyyy-MM-dd-HH-mm.csv

Например:

students-2026-08-28-20-45.csv
  1. Новый файл создаётся в директории, указанной абсолютным путём.
  2. При создании нового файла сначала записывается заголовок.
  3. При успешной записи метод завершается без исключения.
  4. Метод не возвращает значение.
  5. Исключения, связанные с записью файла, не обрабатывать внутри метода — они должны передаваться вызывающему коду.
  6. Исключения Student и StudentBuilder также не обрабатывать.

Невозможность записи

Если студент не может быть записан, например:

  • отсутствуют права на запись;
  • невозможно создать файл;
  • файл недоступен;
  • произошла ошибка файловой системы;

метод должен выбросить соответствующее исключение, например IOException.

Запись не должна возвращать специальное значение вроде 0 для обозначения ошибки.


StudentCsvReader

Назначение

Последовательно читать студентов из CSV-файла.

Контракт

Класс должен реализовывать:

Iterator<Student>

Конструктор:

public StudentCsvReader(String absoluteFilePath)

Методы:

@Override
public boolean hasNext()
@Override
public Student next()

Требования к hasNext()

  1. Проверяет наличие следующей записи Student.
  2. Заголовок CSV не считается записью.
  3. Повторный вызов hasNext() не должен пропускать следующую запись.
  4. После окончания файла метод возвращает false.

Требования к next()

  1. Возвращает следующего Student.
  2. Student создаётся через существующий StudentBuilder.
  3. При отсутствии следующего элемента выбрасывается:
NoSuchElementException
  1. Весь файл не должен предварительно загружаться в коллекцию.

Невозможность прочитать студента

Если следующую запись невозможно прочитать или преобразовать в Student, например:

  • некорректный формат CSV;
  • отсутствует обязательное поле;
  • значение невозможно преобразовать в нужный тип;
  • данные не проходят валидацию Student;

исключение должно передаваться вызывающему коду.

Исключения Student и StudentBuilder не перехватывать и не обрабатывать.

Некорректные записи не должны молча пропускаться.


Общие требования

  1. Оба класса принимают абсолютный путь к файлу.
  2. Использовать готовую библиотеку для работы с CSV.
  3. Не реализовывать собственный CSV-парсер.
  4. Не использовать стандартные коллекции Java как основное хранилище студентов.
  5. Не дублировать в этих классах валидацию Student.
  6. Не дублировать логику создания Student вне StudentBuilder.
  7. StudentCsvWriter отвечает только за запись.
  8. StudentCsvReader отвечает только за чтение.

Примеры тестов

StudentCsvWriter

Создание нового файла

Передать путь к несуществующему файлу и вызвать:

writer.write(student);

Проверить:

  • файл создан;
  • имя соответствует students-yyyy-MM-dd-HH-mm.csv;
  • присутствует заголовок;
  • студент записан;
  • метод завершился без исключения.

Дозапись

Создать файл с одним студентом и выполнить:

writer.write(student2);

Проверить, что:

  • первая запись сохранилась;
  • student2 добавлен в конец;
  • заголовок присутствует только один раз.

Несколько последовательных записей

writer.write(student1);
writer.write(student2);
writer.write(student3);

Проверить наличие трёх записей в правильном порядке.

Невозможность записи

Передать путь, по которому невозможно создать или открыть файл для записи.

Проверить, что write() выбрасывает IOException.

Не проверять специальное возвращаемое значение — метод ничего не возвращает.


StudentCsvReader

Чтение корректного файла

Для файла:

groupNumber,averageGrade,recordBookNumber
A12,4.5,10001
B07,3.8,10002
C25,4.9,10003

Проверить:

  • hasNext() возвращает true до последнего студента;
  • next() возвращает студентов в правильном порядке;
  • после последнего студента hasNext() возвращает false.

Повторный вызов hasNext()

reader.hasNext();
reader.hasNext();
Student student = reader.next();

Проверить, что первый студент не был пропущен.

next() после окончания файла

После чтения всех студентов вызвать:

reader.next();

Проверить выброс:

NoSuchElementException

Некорректная запись

Передать файл:

groupNumber,averageGrade,recordBookNumber
A12,4.5,10001
INVALID
C25,4.9,10003

Проверить, что ошибка при чтении некорректной записи передаётся вызывающему коду.

Некорректные данные Student

Передать данные, нарушающие ограничения Student.

Проверить, что исключение от Student или StudentBuilder выходит наружу и не перехватывается StudentCsvReader.


Названия файлов

StudentCsvWriter.java
StudentCsvReader.java

Git

Название ветки:

feature/csv-student-io

Conventional Commit:

feat: add csv student reader and writer