Работа с файловой системой #

Васильев Андрей Михайлович, 2024

Версии презентации

Файловая система #

ФС — это подсистема ядра ОС, обеспечивающая общий и регулируемый доступ к данным на энергонезависимых источниках: жёстких дисках, оптических дисках, твердотельных носителях и т.д.

На физическом уровне каждый такой носитель представляет собой последовательность из блоков одинакового размера

diagram

  • Как обеспечить одновременный доступ нескольких процессов?
  • Как обеспечить защиту данных?
  • Как реализовать защиту от потери энергии?

Логическая структура файловой системы #

Для процессов и конечного пользователя была предложена древовидная структура

  • Единицей организации данных является каталог, который может содержать другие файлы и каталоги
  • Первый каталог файловой системы называется корневым
  • В результате формируется древовидная структура файловой системы

diagram

В задачу ОС входит преобразования логического обращения к дереву файловой системы на обращение к последовательности блоков

Системные вызовы ОС #

Приложение взаимодействует с ФС путём отправки системных вызовов

Рассмотрим ряд системных вызовов POSIX

  • open — открыть файл для взаимодействия, получить файловый дескриптор
  • read — прочитать данные из файлового дескриптора
  • write — записать данные в файловый дескриптор
  • opendir — открыть каталог для чтения содержимого
  • readdir — считать информацию о файлах в каталоге

Данные вызовы сформированы на языке Си

Текущий рабочий каталог #

Для удобства построения путей к нужным файлам была введена концепция текущего рабочего каталога

Без её помощи можно стоить пути только абсолютно, начиная с корневого каталога /

/home/user/my-data/marks.ods

Это соответствует следующей структуре каталогов

/
└── home
    └── user
        └── my-data
            └── marks.ods

С помощью рабочего каталога можно сократить вводимый пользователем путь:

marks.ods

Эти пути будут указывать на один и тот же файл, если текущий рабочий каталог

/home/user/my-data/

Относительный путь #

Путь к файлу = текущий рабочий каталог + относительный путь

/home/user/my-data/ + marks.ods = /home/user/my-data/marks.ods

Относительные пути значительно сокращают скорость работы с нужными файлами, если их правильно применять

Как указывать относительные пути к другим каталогам #

Согласно древовидному представлению мы можем двигаться в трёх направлениях:

  • Вверх, к родительскому каталогу
  • Остаться на месте в текущем каталоге
  • Вниз, в один из подкаталогов

Вверх #

Для движения «вверх» необходимо использовать специальный путь: ..

Например для составления пути к файлу data.txt в родительском каталоге необходимо составить относительный путь ../data.txt

Родительский каталог/
├── Рабочий каталог/
│   ├── cute-animals/
│   │   └── cat.png
│   └── picture.png
└── data.txt

Остаться на месте #

Для указания текущего каталога используется специальное название: .

Для указания пути к файлу picture.png в текущем каталоге следующие формы будут одинаковыми:

  • ./picture.png
  • picture.png
Родительский каталог/
├── Рабочий каталог/
│   ├── cute-animals/
│   │   └── cat.png
│   └── picture.png
└── data.txt

Спуститься вниз в один из подкаталогов #

Для указания пути к файлу cat.png, расположенному в подкаталоге cute-animals необходимо сформировать: cute-animals/cat.png

Родительский каталог/
├── Рабочий каталог/
│   ├── cute-animals/
│   │   └── cat.png
│   └── picture.png
└── data.txt

Рабочий каталог задач Gradle #

При запуске задачи типа javaExec Gradle установит в качестве рабочего каталога каталог проекта, т.е. каталог с файлом build.gradle.kts

Рассмотрим следующую структуру каталогов:

project
├── gradle/
├── gradlew                         
├── gradlew.bat
├── data/
│   └── content.txt
├── settings.gradle(.kts)
├── subproject-a/
│   ├── build.gradle(.kts)
│   └── src/
└── subproject-b/
    ├── build.gradle(.kts)
    └── src

Если будет запущена команда по сборке, описанная в файле subproject-a/build.gradle.kts, то рабочим каталогом будет каталог subproject-a

Для доступа к данным, data/content.txt, внутри такого процесса необходимо сформировать путь ../data/content.txt

Если путь получен от пользователя приложения, то приложению не надо вносить в него изменения

Классы для работы с ФС #

На платформе JVM приложению на языке Kotlin доступны все классы Java плюс ряд функций-расширений, которые упрощают работу с первыми

  • java.nio.Path предоставляет средства для формирования путей
    • Для создания объектов используется статический метод of
    • Для составления относительных путей предоставляются методы resolve и resolveSibling
  • java.io.File предоставляет средства для анализа состояния файлов на файловой системе
  • java.io.FileReader позволяет считывать текстовую информацию из файла

Для облегчения задач считывания и записи файлов Kotlin предоставляет

  • File.readText() — считывает всё содержимое файла и возвращает строку
  • File.writeText() — записывает переданную строку как текст всего файла
  • File.appendText() — записывает переданную строку как

Кодировка строк #

При работе на платформе JVM внутри приложения строки хранятся в кодировке Unicode

При получении текстовых данных из внешних источников JVM необходимо выполнить преобразование данных в Unicode

  • Получение данных из аргументов приложения
  • Получение данных со стандартного потока ввода
  • Получение данных из файловой системы
  • Получение данных из сетевого взаимодействия
  • При записи необходимо выполнить обратное преобразование

При сдаче лабораторной работы внешнее по отношению к приложению окружение будет использовать Unicode, как и в компьютерной аудитории