Работа с файловой системой #
Васильев Андрей Михайлович
Версии презентации
Файловая система #
ФС — это подсистема ядра ОС, обеспечивающая общий и регулируемый доступ к данным на энергонезависимых источниках: жёстких дисках, оптических дисках, твердотельных носителях и т.д.
На физическом уровне каждый такой носитель представляет собой последовательность из блоков одинакового размера
- Как обеспечить одновременный доступ нескольких процессов?
- Как обеспечить защиту данных?
- Как реализовать защиту от потери энергии?
Логическая структура файловой системы #
Для процессов и конечного пользователя была предложена древовидная структура
- Единицей организации данных является каталог, который может содержать другие файлы и каталоги
- Первый каталог файловой системы называется корневым
- В результате формируется древовидная структура файловой системы
В задачу ОС входит преобразование логического обращения к дереву файловой системы в обращение к последовательности блоков
Системные вызовы ОС #
Приложение взаимодействует с ФС путём отправки системных вызовов
Рассмотрим ряд системных вызовов 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.pngpicture.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, как и в компьютерной аудитории