Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# Работа с файлами. Часть I

Работа с файлами в Java может быть реализована разными способами. Как используя различные инструменты, содержащиеся в
Java (пакеты `java.io` и `java.nio`), так и с помощью внешних библиотек, реализующих свои обертки над классами из
вышеуказанных пакетов. Сегодня мы познакомимся с относительно низкоуровневым способом работы с файлами через
функциональность `java.io` – классы `FileInputStream` и `FileOutputStream`, являющиеся наследниками известных
нам `InputStream` и `OutputStream`. В рамках следующего урока рассмотрим другие классы, облегчающие работу с файлами, в
т.ч. немного затронем `java.nio`.

Пока предлагаю ознакомиться со [статьей](https://metanit.com/java/tutorial/6.3.php)

Обратите внимание, что в статье используются **абсолютные пути** к файлам (_«C://SomeDir//notes.txt»_). В большинстве
случаев такая практика считается неприемлемой – ваше приложение может быть запущено на разных компьютерах, с разными
операционными системами (а, следовательно, и файловые системы могут отличаться). В разных системах и символы-разделители
директорий могут быть разные (как минимум, `«/»` и `«\»`).

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

Исходя из вышесказанного, рекомендуется использовать **относительные пути** к файлам. Они строятся на том, что
существует некая текущая директория (в классическом java-приложении это будет директория проекта). Текущая директория
обозначается символом `«.»`. Символом-разделителем для папок будет служить `«/»`. Также, в рамках общего развития,
директория, в которой находится текущая директория, может быть обозначена в абсолютном пути как `«..»`.

Таким образом, если мы хотим записать (или прочитать) файл, который находится в папке с проектом – путь к нему можно
обозначить как _«./notes.txt»_ (название файла взято из статьи на metanit).

Такой подход сам по себе сильно облегчает обращения к файлам. Но в таком случае директория проекта может превратиться в
мешанину из различных файлов – как системных файлов проекта и сопутствующих инструментов (например, _«*.iml»_ файл,
создаваемый IDEA, _«.gitignore»_ для git и прочие, в зависимости от используемых в проекте технологий), так и файлов, с
которыми работает Java-код (в нашем случае – _«notes.txt»_).

Чтобы избежать такой каши, файлы, нужные для самого приложения обычно выносятся в директорию _«resource»_ (в IDEA ее
можно также пометить через _Project Structure_). В ней тоже могут быть созданы свои внутренние директории для удобства
хранения файлов.

Таким образом, в рамках классического приложения файл стоило бы создать в папке _«resource»_, а относительный путь к
нему можно было бы указать как _«./resource/notes.txt»_.

В дальнейшем, при использовании **сборщиков проектов** (_maven_, _gradle_ и др.), **фреймворков** (в нашем случае,
преимущественно _Spring_) и сопутствующих технологий (например, использование _war-_ или _jar-_ архивов для
развертывания приложения на сервере), относительные пути нужно будет прописывать с учетом как используемых инструментов,
так и с поправкой на то, что файл в вашем проекте при локальном запуске и при запуске на сервере может храниться в
разных местах. Кроме того, и работа с директорией _«resource»_ станет намного актуальнее, поскольку она будет хранить не
только файлы, с которыми мы будем работать из Java-кода, но и различные конфигурации и пр.

В любом случае, это будет относительно не скоро. На данном этапе я предлагаю ограничиться двумя правилами:

1. Недопустимо использование абсолютных путей к файлам;
2. Файлы хранятся в директории _«resource»_, код – в директории _«src»_.

#### С теорией на сегодня все!

![img.png](../../../commonmedia/defaultFooter.jpg)

Переходим к практике:

## Задача 1:

Используя класс `Car` (или создав новый класс для сущности _«машина»_, на ваше усмотрение) из
[задачи](https://github.com/KFalcon2022/practical-tasks/tree/master/src/com/walking/lesson19_object_methods/model)
реализуйте сохранение массива машин в файл _carCatalog.txt_

## Задача 2:

Используя _Задачу 1_, реализуйте чтение из _carCatalog.txt_, реализовав сохранение данных в массив `Car`.

## Задача 3 (*):

Реализуйте возможность добавления, удаления и изменения информации о машинах, используя _Задачи 1 и 2_. Работу с файлом
предлагаю вынести в класс `CarRepository`, но вы можете сделать иную реализацию на свое усмотрение.

Все 3 задачи можно реализовать в рамках одного проекта (подпроекта), по сути, задача 3 включает в себя задачи 1 и 2. Но
для удобства реализации чтения и записи, а также фиксации успешных шагов, вы можете также реализовать задачи по
отдельности. Тема не очень сложная, но на ней спотыкаются многие новички, в том числе из-за слишком крупных практических
задач на работу с файлами.

> Если что-то непонятно или не получается – welcome в комменты к посту или в лс:)
>
> Канал: https://t.me/ViamSupervadetVadens
>
> Мой тг: https://t.me/ironicMotherfucker
>
> **Дорогу осилит идущий!**