Работа с файловой системой
#
Васильев Андрей Михайлович
Версии презентации
Файловая система
#
ФС — это подсистема ядра ОС, обеспечивающая общий и регулируемый доступ к данным
на энергонезависимых источниках: жёстких дисках, оптических дисках,
твердотельных носителях и т.д.
На физическом уровне каждый такой носитель представляет собой последовательность
из блоков одинакового размера
- Как обеспечить одновременный доступ нескольких процессов?
- Как обеспечить защиту данных?
- Как реализовать защиту от потери энергии?
Логическая структура файловой системы
#
Для процессов и конечного пользователя была предложена древовидная структура
- Единицей организации данных является каталог, который может содержать другие
файлы и каталоги
- Первый каталог файловой системы называется корневым
- В результате формируется древовидная структура файловой системы
В задачу ОС входит преобразование логического обращения к дереву файловой
системы в обращение к последовательности блоков
Системные вызовы ОС
#
Приложение взаимодействует с ФС путём отправки системных вызовов
Рассмотрим ряд системных вызовов POSIX
open — открыть файл для взаимодействия, получить файловый дескриптор
read — прочитать данные из файлового дескриптора
write — записать данные в файловый дескриптор
opendir — открыть каталог для чтения содержимого
readdir — считать информацию о файлах в каталоге
Данные вызовы описаны на языке Си
Текущий рабочий каталог
#
Для удобства построения путей к нужным файлам была введена концепция текущего
рабочего каталога
Без её помощи можно строить пути только абсолютными, начиная с корневого
каталога /
/home/user/my-data/marks.ods
Это соответствует следующей структуре каталогов
/
└── home
└── user
└── my-data
└── marks.ods
С помощью рабочего каталога можно сократить вводимый пользователем путь:
Эти пути будут указывать на один и тот же файл, если текущий рабочий каталог
Относительный путь
#
Путь к файлу = текущий рабочий каталог + относительный путь
/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.file.Path — интерфейс, предоставляет средства для формирования
путей
- Для создания объектов используется статический метод
of
- Для составления относительных путей предоставляются методы
resolve и
resolveSibling
java.io.File предоставляет средства для анализа состояния файлов на файловой
системе
File.exists() проверяет существование файла или каталога
File.isFile проверяет, что путь указывает именно на файл
java.io.FileReader позволяет считывать текстовую информацию из файла
(не рекомендуется для нового кода; новые приложения используют
функции Kotlin ниже)
Для облегчения задач считывания и записи файлов Kotlin предоставляет
File.readText() — считывает всё содержимое файла и возвращает строку
File.readLines() — считывает содержимое файла и возвращает список строк
File.writeText() — записывает переданную строку как текст всего файла
(существующее содержимое файла заменяется)
File.appendText() — дописывает переданную строку в конец файла
Пример работы с файлом
#
Проверка существования и чтение файла, путь к которому получен в аргументах:
import java.io.File
import kotlin.system.exitProcess
fun main(args: Array<String>) {
if (args.isEmpty()) {
println("Ошибка: не указан путь к файлу")
exitProcess(1)
}
val file = File(args[0])
if (!file.exists() || !file.isFile) {
println("Ошибка: файл ${args[0]} не найден")
exitProcess(1)
}
val lines = file.readLines()
println("Строк в файле: ${lines.size}")
}
Объект File можно создать и из относительного пути — он будет разрешён
относительно текущего рабочего каталога процесса.
Кодировка строк
#
При работе на платформе JVM внутри приложения строки хранятся в кодировке
Unicode
При получении текстовых данных из внешних источников JVM необходимо выполнить
преобразование данных в Unicode
- Получение данных из аргументов приложения
- Получение данных со стандартного потока ввода
- Получение данных из файловой системы
- Получение данных из сетевого взаимодействия
- При записи необходимо выполнить обратное преобразование
При сдаче лабораторной работы внешнее по отношению к приложению окружение будет
использовать Unicode, как и в компьютерной аудитории