Особенности файловой системы NTFS
АрхивВ последнее время аппаратные средства стремительно дешевеют (в долларовом эквиваленте), и все большее число пользователей получает в распоряжение ресурсы, вполне достаточные для работы операционной системы Microsoft Windows NT (Pentium MMX 200 МГц, 32-64 Мбайт RAM). К мысли о переходе на NT приводит ненадежность и непредсказуемость Windows 95/98, а также их неспособность оптимально управлять ресурсами современных компьютеров.
При этом многие неискушенные пользователи не находят для себя ничего кардинально нового. И действительно, установив Internet Explorer 4 и не пользуясь многочисленными возможностями NT по усилению безопасности и защиты вычислительной системы, самое большое отличие от Windows 98, которое можно найти, это наличие двух папок "Автозагрузка" в пусковом меню (текущего пользователя и общей для всех пользователей) и отсутствие апплета Add/Remove Hardware в "Панели управления". А если еще и не форматировать диск под файловую систему NTFS, разницы не будет и подавно.
Ниже я хочу рассказать как раз о некоторых преимуществах NTFS перед FAT, VFAT, FAT16 и FAT32. Общеизвестные отличия, такие как способность к самовосстановлению, отложенная запись, максимальный размер тома и файла на нем (до 16 экзабайт; 1 экзабайт = 1000000 гигабайт), возможность сжатия отдельных файлов и папок, установки разрешений и аудита, достаточно широко освещены в литературе и документации к Windows NT. Но существуют еще малоизвестные и малоиспользуемые возможности NTFS: жесткие ссылки (hardlinks) и множественные потоки данных (multiply data flows или forks). Далее пойдет речь именно о них.
Множественные потоки данных. Этот термин знаком пользователям Macintosh. В этой системе файл может иметь два потока (forks): поток данных и поток ресурсов. В потоке данных хранятся собственно данные файла - этот поток и копируется как единственный при переносе файла с Macintosh на PC. Второй поток файла - поток ресурсов, содержащий данные операционной системы: меню, значки, шрифты, - словом, все то, что принято называть ресурсами. Когда Windows NT Server обслуживает клиентов Macintosh и предоставляет им дисковое пространство для хранения файлов, необходимо, чтобы файловая система сервера поддерживала формат файлов клиента. Это является одной из причин появления множественных потоков данных в NTFS.
Каким образом это реализовано? Любая информация о файле, начиная с его имени, прав доступа и заканчивая собственно данными, хранящимися в файле, с точки зрения NTFS представляет собой атрибут, хранящийся в собственном потоке (stream). Разработчики NTFS решили не ограничиваться одним потоком для данных, безымянным, и добавили возможность создания нескольких, помимо основного, именованных потоков. Для создания множественных потоков можно применить функцию Win32 API, но есть пути и проще.
Со времен Кернигана и Ричи, разработчиков языка C и операционной системы Unix, у многих операционных систем существует возможность обобщения операций ввода/вывода. С этой точки зрения любая операция ввода/вывода может рассматриваться как операция ввода из потока или вывода в поток независимо от того, что является источником данных (консоль, то есть клавиатура, файл или порт) и приемником (опять же консоль, в данном случае уже экран монитора, принтер или файл). Существует и возможность перенаправить ввод/вывод программы с экрана на принтер и вводить команды не с клавиатуры, а из файла. В наше время повсеместного использования графического пользовательского интерфейса эти возможности применяются очень редко, поэтому поясню сказанное примером.
Команда echo операционных систем Microsoft используется для вывода информации на экран в текстовом режиме:
C:\>echo Hello, World!
Hello, World!
C:\>
Команда echo в качестве устройства вывода информации использует экран монитора. Вывод этой команды можно перенаправить с консоли в файл (для этого используется символ ">"):
C:\>echo Hello, World! > file
C:\>
Как видите, команда echo в данном случае на экран ничего не вывела. Но в файле file можно обнаружить строку "Hello, World!". Аналогично вывод команды echo можно перенаправить и на принтер:
C:\>echo Hello, World! > lpt1
C:\>
На экране опять ничего, но на листе бумаги можно обнаружить все ту же строку "Hello, World!", если, конечно, принтер подсоединен к порту lpt1. Таким образом, вывод любой программы текстового режима можно перенаправить на любое устройство, поддерживающее потоковый ввод информации, или в файл, за исключением тех программ, которые в текстовом режиме используют для вывода информации непосредственную модификацию видеопамяти и другие нестандартные, с точки зрения классического C, возможности.
Аналогично можно перенаправить и ввод программы. Команда more операционных систем Microsoft используется для буферизации вывода команд, выводящих информации больше, чем умещается на экран. Но эту команду можно использовать и для иллюстрации перенаправления ввода:
C:\>more < file
Hello, World!
C:\>
В файле file находилась строка "Hello, World!", которая была направлена на экран.
Точно так же, с помощью перенаправления ввода/вывода, можно создавать и читать множественные потоки данных:
C:\>echo string1 > file:fork1
Записью file:fork1 определяем в файле file поток с именем fork1 (поскольку он еще не существует, то создается новый с этим именем) и перенаправляем в него вывод команды echo. При этом размер файла при просмотре его свойств не изменяется, и стандартными средствами Windows NT, не зная имени потока, его существования определить нельзя. Но, зная его имя, можно с помощью команды more определить и его содержимое:
C:\>more < file:fork1
string1
Таким образом, можно создавать и читать содержимое потоков данных файла. Количество потоков, создаваемых в одном файле, ограничено только объемом свободного пространства на жестком диске. Аналогично создаются потоки данных в каталогах, но для просмотра содержимого потока придется применить другое средство вывода потока на экран, так как команда more при этом выдает следующую ошибку:
The instruction at "0x010013c2" referenced memory at "0x0061004d". The memory could not be "read".
Если ничего подходящего найти не удалось, можно создать в любом компиляторе C++ такую программу:
#include <iostream.h>
void main ()
{
char ch;
while (cin.get(ch)) cout.put(ch);
}
Скомпоновать эту программу лучше как консольное Win32-приложение и использовать как средство для изучения потоков каталогов.
Windows NT не предоставляет стандартных средств для получения информации о множественных потоках данных. Но что делать, если такая информация необходима? В этом случае можно воспользоваться программой streams Марка Руссиновича (Mark Russinovich), доступной, вместе с исходным кодом, на сайте www.sysinternals.com. В ней для получения информации о множественных потоках данных используются недокументированные функции Windows NT. Вот информация, полученная с помощью программы streams о файле file:
C:\>streams file
NTFS Streams Enumerator v1.0
Copyright (C) 1999 Mark Russinovich
Systems Internals - www.sysinternals.com
file:
:fork1:$DATA 10
C:\>
Здесь можно видеть как название потока данных, так и его размер в байтах (дополнительные три символа - это пробел перед символом ">", возврат каретки и перевод строки, добавляемые командой echo). К сожалению, streams не позволяет определить множественные потоки данных в каталогах.
Каковы пути применения множественных потоков данных? Помимо применения, найденного для них фирмой Apple, можно указать на самое простое средство для скрытия информации, например, для запоминания даты установки программы shareware. На заре технологии OLE компания Microsoft предполагала использовать потоки данных для хранения информации о внедренных объектах, но, видимо, обеспечить потоки данных на FAT оказалось сложнее, чем создать длинные имена файлов, и от этой идеи пришлось отказаться. Создание "файла ресурсов" для скрипта с хранением в нем всех надписей, выводимых на разных языках, также может быть интересной областью применения потоков. Помимо приведенных, существует множество других интересных применений для множественных потоков данных.
Жесткие ссылки. Пользователям различных клонов Unix хорошо знакомо это понятие. В отличие от файловой системы FAT, в которой принято, что у каждого файла может быть только одно имя, Unix от такого ограничения освобождена: каждый файл может иметь несколько имен, и его данные не могут быть удалены, пока счетчик имен файла не равен нулю. В Unix существуют также символьные ссылки - аналог ярлыков (shortcut) в Windows, но следящие за перемещением объекта, на который они ссылаются.
Windows NT ограниченно соответствует стандарту POSIX (Portable Operating System Interface for Computing Environments). Один из примеров ограниченности - поддержка жестких ссылок и отсутствие поддержки символьных. Видимо, было решено, что ярлыки являются достойным аналогом символьных ссылок.
В NTFS жесткие ссылки организованы аналогично множественным потокам данных: если у файла есть несколько потоков с данными, почему не может быть нескольких потоков с именами? Несколько имен файла могут находиться в разных каталогах, но только в пределах одного раздела.
Для изготовления жесткой ссылки необходима программа для подсистемы POSIX Windows NT. Такая программа вместе с исходными текстами находится на компакт-диске "Ресурсы Windows NT". По аналогии с Unix эта программа называется ln. Синтаксис этой команды:
C:\>Ln file hardlink1
С помощью этой команды мы создаем для файла file второе имя, или жесткую ссылку hardlink1. При изменении содержимого файла file изменяется и содержимое hardlink1, то есть по сути это один и тот же файл, но с двумя именами. Аналогично можно менять и другие атрибуты файла. Количество имен у файла не ограничено, но при копировании имени файла ссылка разрывается, и создается еще один файл. Существует возможность создания ссылки в другом каталоге:
C:\>Ln file ../temp/hardlink2
В этом случае необходимо указывать не абсолютное, а относительное имя каталога.
Для жестких ссылок можно найти не меньше применений, чем для множественных потоков данных. Например - создавать жесткие ссылки для библиотек dll, чтобы обезопасить свою программу от случайного удаления необходимого файла. Другие возможные применения жестких ссылок лучше всего искать в литературе, относящейся к Unix. И, конечно же, применение жестких ссылок можно комбинировать с описанными выше множественными потоками данных.
Автор не претендует на полный охват рассмотренной темы и будет рад принять замечания и дополнения.