Что такое файловая система

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

Файловые системы — это системы организации хранения файлов и папок на диске. Понимание того, как они устроены, часто помогает в разработке и отладке программ. Но не только!

Как компьютер хранит данные

Любой жёсткий диск — это набор хранимых битов информации, единиц и нулей, объединённых в блоки по 8 бит, образующие байты. SSD или флешки используют много-много специальных транзисторов, которые хранят заданное значение очень долго, даже обесточенные.

Эти транзисторы умеют хранить двоичное значение, 0 или 1, это и есть бит информации. А на пластины классических крутящихся дисков нанесён ферромагнитный сплав, на каждом из участков которого может быть установлен заряд — и позднее прочитан. Редкие в наше время дискеты, CD, DVD и магнитные ленты работают по схожему принципу, просто механизм записи и чтения у них иной.

Важно знать, что на уровне самого жёсткого диска нет никаких файлов или каталогов, есть только каша из нулей и единиц — и всё!

У жёстких дисков есть контроллер, с которым операционная система общается через драйвер. Когда вы открываете файл с фильмом, она говорит драйверу: «Сместись на несколько ячеек и прочитай мне такой-то адрес».

Если у вас диск объёмом 1 ТБ, он хранит примерно 10¹² байт. А чтобы прочитать файл длиной 4 КБ (то есть 4096 байт) откуда-то из середины диска, операционная система попросит: «Прочитай мне данные с места 5 000 000 000 000 по 5 000 000 004 095». И жёсткий диск вернёт как раз 4096 байт информации. Но на уровне драйвера жёсткого диска тоже нет никаких файлов и каталогов...

При чём тут файловая система

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

На диске есть небольшая область, где собрана информация о разделах диска, — таблица разделов. Она хранит данные о том, где каждый раздел начинается и заканчивается. Именно за счёт неё можно поделить один физический диск на разделы (partition).

То есть пустой раздел диска — это область, где по мере сохранения файлов у нас будет записана информация обо всех файлах и много пустого места.

Представьте себе хорошо знакомый лист в клеточку. Наверху мы напишем, в какой части листа у нас какой раздел, а потом разделим его на зоны. Каждая такая зона будет отдельным разделом. В одной части листа мы будем писать заметки, в другой — рисовать графики, а сверху у нас будет описание, какая зона для чего предназначена.

Всё место внутри раздела делится на блоки (а для старых крутящихся дисков — на сектора). Это небольшие отрезки размером в несколько килобайт (пропорционально размеру диска, для привычных нам дисков в 0,5–10 ТБ один блок или сектор обычно будет 4 КБ), которые выделяются для хранения каждого файла.

Файл размером 842 байта занимает на диске 4 КБ. Это как раз один блокФайл размером 842 байта занимает на диске 4 КБ. Это как раз один блок

Когда мы создаём файл, драйвер диска находит свободное место для него, записывает себе адрес этого файла на диске в табличку и сохраняет. Теперь мы знаем, в каком блоке диска искать этот файл. Если наш файл размером больше одного блока, файловая система находит свободный блок на диске, записывает туда один из блоков файла, а когда закончится первый блок — находит следующий и пишет туда, пока вся информация не будет записана. Информацию, где позже искать блоки, система сохраняет в табличку со сведениями обо всех файлах.

Вернёмся к нашему листочку. Каждая клетка будет соответствовать одному блоку. Если нам надо записать цифру, мы поместим её в одну клетку, а если надо написать предложение, оно займёт несколько клеток. Запись предложения наверняка будет занимать все свободные клетки подряд: например, половина первого слова влезает в две клетки, после мы пропустим несколько уже занятых клеток и допишем остаток предложения в свободные.

Например, у нас есть файл размером в 2,5 блока, то есть 10 КБ. Диск у нас более или менее заполнен, так что, когда мы сохраняем файл, может получиться, что он сохранён в блоки 212, 213 и 20 517. Да, два первых блока идут рядом, а третий где-то далеко от них. Но файловая система знает, где их искать, так что, когда нам потребуется прочитать этот файл, мы прочитаем его весь.

С папками всё ещё проще. Сама по себе папка ничего не весит, это всего лишь способ группировать наши файлы, так что, создавая папку, мы указываем в табличке с информацией, что файлы лежат в такой-то папке.

Интересная вещь происходит, когда мы удаляем файл. Мы помним, что файл у нас — это и запись в табличке, где его искать, и номера блоков, где он лежит. Так вот, когда мы удаляем файл, мы стираем указатель в табличке, а система считает выбранную последовательность блоков свободной. Когда мы будем сохранять какой-то другой файл, система может разместить его в том же месте.

Зная информацию из удалённых файлов, мы можем попытаться найти и восстановить содержимое блоков на диске. Так устроено низкоуровневое восстановление данных.

Ещё стоит упомянуть, что и драйвер диска, и контроллер очень любят все оптимизировать. Например, вы переносите файл с одного диска на другой, а конечный диск занят чем-то ещё. В таком случае часть файла может остаться в оперативной памяти компьютера или контроллера диска — и через какое-то время (обычно небольшое) эти данные будут записаны на диск. Это сильно ускоряет работу системы, но часто приводит к неприятным последствиям.

Когда окно со статусом копирования исчезло, вам кажется, что система уже скопировала файл. Вы выдёргиваете флешку, но потом обнаруживаете, что файл не читается или отсутствует.

Твердотельные диски любят оптимизировать хранение файлов, не последовательно записывая данные, а распределяя их по реже использовавшимся ячейкам. Это связано с тем, что используемая в них память имеет большой, но ограниченный ресурс перезаписи. И если постоянно перезаписывать ячейки диска в начале, не трогая остальные, то они первыми исчерпают ресурс.

А более старые, крутящиеся диски умели сами находить повреждённые сектора на своих пластинах. Они отмечали у себя в контроллере, что этот сектор больше не работает, и сами перемещали данные из них в исправные участки. Это приводило к тому, что со временем диск начинал работать медленнее и у него уменьшался доступный объём.

Как хранение данных связано с операционной системой

А теперь поговорим о специфике разных систем. Самая простая и распространённая — это FAT, File Allocation Table, «таблица расположения файлов». У неё есть несколько вариаций: FAT12, FAT16, FAT32 и exFAT, она же FAT64. Число в названии — это размер номера блока в битах.

Если вам показалось, что 12 бит для номера блока в FAT12 — это мало, то вы абсолютно правы! Эта операционная система изначально могла работать с разделами до 2 МБ, а с принудительным увеличением размера блока — с разделами до 32 МБ. Сейчас это кажется смешными значениями, но в 1980-х, когда применялась FAT12, этого было более чем достаточно. На современных флешках вы, скорее всего, встретите FAT32 или FAT64, и там размер раздела будет варьироваться от 8 ГБ в FAT32 до 16 ЭБ в FAT64.

Интересно, что во всех системах FAT максимальная длина имени файла или каталога — 8 символов, а для хранения расширения файла отведено 3 символа. «Как так, я же спокойно могу записать на флешку файл с длинным именем?» — скажете вы. И будете правы.

Но если вы посмотрите на свою флешку с помощью специальной утилиты, то увидите, что ваш файл с именем Squid_Game_S2E01.mkv на самом деле называется Squid_~1.mkv.

Всё остальное имя файла хранится в специальной надстройке и занимает дополнительное место (мало места, если быть честным), а ваша операционная система не хочет раздражать вас этими короткими именами и сразу показывает длинное имя. Ещё FAT редко пересчитывает свободное место, вместо этого она хранит в табличке с файлами запись о количестве свободных блоков, но старается обновлять это число, чтобы информация была актуальной. При помощи специальной утилиты можно вручную поменять количество свободных блоков — и из флешки на 4 ГБ сделать флешку на 20 ТБ. Правда, записать столько данных вы туда всё равно не сможете (а жаль).

Поговорим ещё о проблеме фрагментации файлов в FAT. Эта система распределяет блоки файлов, проходя от начала к концу в поисках свободного места. Поскольку информацию, разделённую на блоки, она последовательно записывает в каждый свободный слот, блоки файлов на диске могут быть сильно перемешаны, от этого их чтение замедляется.

Для исправления этого недостатка создали программу дефрагментации. Она считывает разрозненные блоки файла и записывает их заново, единым блоком. При регулярной дефрагментации FAT-диска он будет как новенький!

ДефрагментацияДефрагментация

Другая файловая система, NTFS, имела много преимуществ перед FAT.

Например, в FAT метаданные о файлах хранились отдельно, в виде дополнительного файла, а в NTFS — в таблице с файлами. Там содержалась информация о правах доступа, это позволяло разграничивать, кто какие файлы может читать и менять.

Хорошая идея — защитить файлы операционной системы от случайного изменения. Также оказалось удобно добавить в метаданные информацию о характеристиках файла, например битрейт для аудио и видео или размер картинки. Другой важной новинкой стало то, что у файлов появились потоки данных, streams. Это позволило хранить в одном месте несколько версий файлов (видели вкладку «Предыдущие версии» в свойствах файла?) и держать там дополнительные данные: например, некоторые антивирусы отмечают файлы, которые они проверили.

Последним важным улучшением стала возможность вести журналы, то есть записывать всю историю работы с файлами на этом диске. Это, конечно, сильно нагружает файловую систему, но очень помогает в отладке и поиске проблем. А ещё NTFS умеет экономно хранить маленькие файлы. В табличке отведено очень много места для имени файла. Если файл настолько мал, что его можно записать после собственного имени, эта система не выделяет блок на диске, а умещает файл прямо в табличку.

Появилось и ещё несколько удобных штук, преимущественно для серверной инфраструктуры: например, иерархическое назначение прав, возможность задать квоты на использование места и так далее. Если вы используете компьютер под управлением Windows, скорее всего, на ваших дисках именно NTFS.

И ещё парочка систем!

Рассмотрим другие системы: HFS и APFS для компьютеров Apple, ext, с которой работает Linux, и XFS. Они организованы по-разному, но имеют много похожих принципов.

Первое, что бросается в глаза, это разница в подходе к именам файлов и папок. В Windows вы не можете создать рядом File1.txt и file1.txt, потому что с точки зрения тамошних файловых систем это будет один и тот же файл. А вот в этих файловых системах учитывается разница между строчными и заглавными буквами, так что файлы будут спокойно лежать рядом и не мешать друг другу.

Ещё в них ограниченное распределение прав на файлы и папки. У каждого файла или папки есть пользователь-владелец и группа-владелец, а также назначенные права «читать», «писать» и «выполнять» для группы и для владельца. После NTFS, где вы могли назначить файлу сколько угодно прав, это кажется недостаточным, но при вдумчивом подходе к организации прав пользователей это не будет проблемой.

Также, в отличие от NTFS, где каждому разделу диска присваивалась буква латинского алфавита, файловые системы HFS и APFS содержат всё в едином дереве каталогов. Например, если у вас есть диск с вашими рабочими файлами и диск с системой, то в Windows это могли бы быть диски D: и C:. А в этих файловых системах системный диск станет /, то есть корневой папкой, а диск с вашими файлами, скорее всего, будет /home/user, то есть просто выглядеть как папка внутри. С непривычки это сбивает с толку, но на самом деле даёт много удобства и гибкости.

Стоит упомянуть виртуальные и сетевые файловые системы. Их очень много, и у каждой обычно есть своя специфика, но все они служат надстройкой над «реальной» системой и обращаются к ней, когда им нужно работать с папками и файлами.

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

Ну и напоследок...

Сложно сказать, когда именно появились файловые системы. В XIX веке для жаккардовых ткацких станков использовали карточки с отверстиями, которые определяли получающийся узор. И их хранили стопочками в каталогах.

Потом первые компьютеры использовали перфокарты, те же бумажные и картонные таблички с отверстиями. А позже начали использовать магнитные ленты для записи данных. Конкретное расстояние на этой ленте оператор подписывал ручкой. И всё убиралось в каталоги — большие железные шкафы с выдвижными ящиками.

Буквально, бобина магнитной ленты, на которой было написано «0–2 м — данные Боба, 2–7 м — данные Алекса, 7–20 м — танцевальная музыка», могла лежать в каталоге, в ящике «Дела на потом».

Сложно назвать это файловой системой, но узнаваемые принципы уже прослеживаются. Затем по такой же схеме использовались аудиокассеты.

Вроде бы и не похоже, но вот носитель — и понятно, где и что на нём хранится. В целом чем не файлы?Вроде бы и не похоже, но вот носитель — и понятно, где и что на нём хранится. В целом чем не файлы?

В 50-х годах для компьютеров тех времён было несколько систем, где жёсткие диски делились между пользователями. Например, IBM 305 RAMAC в 1956 году или IBM 709 с поддержкой Compatible Time-Sharing System в 1958. У каждого пользователя был свой раздел диска, заданный смещением от начала, и каждый сам должен был указывать, в каких блоках будет храниться файл. По сути, пользователь руками делал то, чем сегодня занимаются драйверы диска.

В 1964 вышла операционная система Multics, в которой впервые появились файлы и папки в привычном нам виде. В 1969 была создана UFS, Unix File System, а в 1977 — FAT для MS-DOS.

В это время выходило немало и других операционных систем, у которых были свои файловые системы, но у них ещё не было названий, и отдельно они не сохранились. В 1984 году появилась MFS, Macintosh File System, для компьютеров Macintosh от Apple, которая потом стала HFS для macOS.

В дальнейшем файловые системы развивались, следуя за увеличением размера дисков и повышением требований к надёжности и скорости, пока мы не пришли в эру интернета. Понадобилось иметь много гибких вариантов файловых систем для разных случаев, а ещё появилась виртуализация и распределённые системы, которые потребовали таких же файловых систем для себя...

Но это уже совсем другая история!