hex.pp.ua

Разреженные файлы NTFS

Внутреннее устройство разреженных файлов NTFS




Разреженные файлы в Windows это такие файлы, которые занимают меньше дискового пространства, чем их реальный размер. При этом не используется сжатие данных. Экономия места в разреженных файлах достигается за счёт компактного представления пустых областей файла, которые содержат одни лишь нули (символы 0x00). По-английски разреженные файлы называются sparse files.

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

Файл делится на логические блоки размером 64 Кб. Анализируется каждый такой блок. Если любой байт в пределах блока имеет значение, отличное от 0x00, значит этот блок не пустой, он содержит данные. Блок, содержащий данные пишется на диск. Если же все байты в пределах блока имеют одинаковое значение 0x00, такой блок считается пустым. Содержимое такого блока вообще не сохраняется на диск.

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

Проверка разреженности fsutil
Проверка разреженности командой fsutil

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

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

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

Двоичное представление данных

С помощью программы NTFS Stream Explorer 1.07 я исследовал внутреннее устройство разреженных файлов. Вообще-то эта версия не показывает, как устроены такие файлы на диске, вместо этого она показывает их в виде формата Microsoft Backup (используемого в функциях BackupRead и BackupWrite). Это особый формат представления файлов, созданный Microsoft для целей архивации и резервного копирования. Устройство разреженных файлов в этом формате может не отображать реального положения вещей, но может показать некоторые принципы хранения таких файлов.

Создадим для экспериментов пустой файл размером 256 Кб, зададим ему атрибут «разреженный» и установим диапазон разреженности, равный его длине. Сделаем все эти операции с помощью системной консольной утилиты fsutil:


fsutil file createnew file 262144
fsutil sparse setflag file
fsutil sparse setrange file 0 262144

Откроем файл в программе NTFS Stream Explorer, чтобы посмотреть его внутренее представление в виде потоков. В списке потоков отобразится один безымянный поток, имеющий тип «Блок разреженного файла», размером 8 байт.

Блок разреженного файла
Блок пустого разреженного файла

Этот восьмибайтный поток хранит размер разреженного файла. Убедиться в этом можно, если экспортировать содержимое потока во внешний файл, а затем открыть его в 16-ричном редакторе. Также можно сдампить содержимое всех потоков файла сразу, используя программу NTFS BackupRead Dumper.

Сделаем дамп всех потоков и получим дамп размером всего лишь 48 байт:

Дамп разреженного файла
Дамп пустого разреженного файла
Разреженный файл 15 Тб
Разреженный файл размером 15 Тб

На картинке выделен sparse-поток. Его последние восемь байт содержат размер файла. Действительно, созданный файл имеет размер 256 Кб, в шестнадцатиричной системе счисления это 0x40000. Попробуем поменять это значение в hex-редакторе на какое-нибудь другое и восстановим файл из дампа с помощью NTFS BackupRead Dumper. Восстановленный файл назовём file2. Например, можно поменять значение 00004000 00000000 на 00000000 000F0000. Проверим размер восстановленного файла в диалоге его свойств (на картинке справа).

Как видно, восстановленный файл получился размером 15 терабайт, но на диске по-прежнему занимает всего лишь 4 Кб. Технология разреженных файлов позволяет создавать очень большие файлы. Размер файла даже может превышать размер жёсткого диска, на котором он расположен. Так, на моём жёстком диске, разумеется, нет свободного места для 15 терабайт.

Итак, видно, что пустой разреженный файл хранит на диске только собственный размер. Теперь нужно записать что-нибудь в разреженный файл, чтобы увидеть, как устроены потоки sparse-данных. Возьмём hex-редактор, и запишем что угодно по любому смещению нашего гигантского разреженного файла. Откроем file2 в NTFS Stream Explorer, чтобы посмотреть, какие потоки он содержит теперь. Видно, что потоков стало два.

Блок разреженного файла с данными
Блок разреженного файла с данными

Второй разреженный поток размером 65544 байт это поток данных разреженного файла. Его первые 8 байт занимает смещение, по которому начинается данный блок в файле. Остальные байты это байты данных. 65544 - 8 = 65536, а значение 65536 это 64 Кб — минимальный размер логического блока внутри sparse-файла. Если произвести запись в соседний блок, то он увеличится уже до 128 Кб. Также файл может содержать несколько sparse-блоков с данными.

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

См. также

  • Утилита sparser. Может устанавливать атрибут разреженности у заданного файла, проверять наличие этого атрибута, задавать диапазоны разреженности, а также самостоятельно искать в файле пустые области и помечать их разреженными.
  • Баг в функции BackupSeek, связанный с неправильным пропуском разреженных блоков при получении списка потоков у файла. NTFS Stream Explorer умеет корректно отображать список потоков разреженных файлов, так как в программе был найден способ обхода данной ошибки.
  • NTFS Stream Explorer — программа для отображения списка потоков NTFS и выполнения операций с ними. В статье упоминается версия 1.07. Начиная с версии 2.00, программа работает с разреженными файлами иным способом.
  • NTFS BackupRead Dumper — программа для полного дампа потоков файла и восстановления файла из дампа.

По теме разреженных файлов также есть следующее:

система комментирования CACKLE

Автор: амдф
Дата: 03.04.2011


Разделы сайта
Главная
Блог
Native API
NTFS и ReFS
Микроконтроллеры
Справочник NTDLL
Коды NTSTATUS
Разное

Избранное
NTFS Stream Explorer
Native Shell
Тенгвар

Остальное
nvpnhcknn (архив)
English pages
Контакты

Ленты atom
Лента Atom сайта Лента Atom блога



При копировании материалов хорошим тоном будет указание авторства и ссылка на сайт.