При получении информации на странице свойств выполняется простой рекурсивный поиск всех файлов в папке. При этом не предпринимаются попытки отфильтровать имена файлов, ссылающиеся на один физический файл, используя жесткие ссылки. Если у вас нет доступа к какой-то подпапке, рекурсивный поиск проигнорирует ее и размер файлов в ней в общую цифру не попадет.
Но оказывается, что в рекурсивном поиске по подпапкам есть свои хитрости. Одна из «особых» хитростей: точки повторной обработки обнаруживаются и рекурсивные переходы по ним не производятся. Другая хитрость обусловлена простым совпадением: размер символических ссылок на файлы не засчитывается. Причина не в особой «мудрости» кода поиска по подпапкам, а в том, что в файловой системе размер символических ссылок считается равным нулю. Теперь мы знаем, как считается размер файлов, но откуда берутся упомянутые цифры?
Измерение размера не составляет проблем — надо просто получить перечень размеров всех файлов, возвращенных функцией FindFirstFile в структуре WIN32_FIND_DATA (nFileSizeLow и nFileSizeHigh). Но надо помнить, что эти цифры не обязательно верны из-за особенностей обновления записей каталога в файловой системе NTFS. Этому можно посвятить целую книгу, но вкратце суть в том, что возвращенная информация о размере файлов, запись которых не завершилась, не совсем верна, пока не будет закрыт описатель файла. Но даже после этого будет обновлена запись в каталоге, использованная для открытия файла.
С параметром «На диске» (Size on disk) все еще сложнее. Если диск поддерживает сжатие (что можно узнать по состоянию флага FILE_FILE_COMPRESSION, возвращенного функцией GetVolumeInformation) и файл является сжатым или разраженным (флаги FILE_ATTRIBUTE_COMPRESSED, FILE_ATTRIBUTE_SPARSE_FILE), значение параметра «На диске» этого файла будет равным значению, возвращенному функцией GetCompressedFileSize.
Это размер сжатого файла (если он сжат) или размер файла за вычетом незанятых частей, которые логически считаются пустыми (если это разреженный файл). Если файл не разрежен и не сжат, параметр «На диске» равен значению, возвращенному функцией FindFirstFile, после его округления до ближайшего кластера.
Изначально алгоритм вычисления параметра «На диске» был создан разработчиками Windows 95. Их понимание строения файловой системы происходило из знаний, полученных при работе с MS-DOS. В то время единственной дисковой файловой системой была FAT. Таких вещей, как жесткая ссылка или альтернативный поток данных, еще не существовало. Содержимое файлов хранилось в кластерах.
Все эти принципы в NTFS не работают — даже принцип хранения файлов в кластерах. В NTFS файл может занимать нуль кластеров под данные, разместившись в пространстве основной таблицы файлов (master file table, MFT). Подробнее см. статью The Four Stages of NTFS File Growth. Естественно, что в параметре «На диске» не учитывается пространство, необходимое файловой системе для хранения файла, такое как место, занимаемое именем файла, записью в каталоге, метаданными файла и альтернативными потоками данных.
Значения, отображаемые в параметрах «Размер» (Size) и «На диске» (Size on disk) не нужно использовать, как точный размер «до байта» общего пространства, занимаемого файлами на диске. Это всего лишь грубая оценка, основанная на предположении, что большинство файлов стандартно, а файлов экзотических форматов нет или очень мало. Я имею в виду, что нет жестких ссылок и пренебрежительно мало альтернативных потоков данных. Если в вашем каталоге много жестких ссылок, таких как, например, сами Windows-каталоги, цифры на странице свойств будут неверными.
Можно использовать параметр «На диске» как оценку размера папки, но имейте в виду, что это очень базовая цифра. Если нужно внимательно следить за использованием дискового пространства, лучше воспользуйтесь дисковыми квотами, которые позволяют более точно выполнять эту задачу.
Комментарии (0)