Рис. 6.17. Чтение файла, состоящего из логических записей: до чтения записи 19 (а);
после чтения записи 19 (б)
Основная виртуальная команда вывода записывает логическую запись из памяти в файл. Последовательные команды write выполняют последовательные логические записи в файл.
Реализация виртуальных команд ввода-вывода
Чтобы понять, как реализуются виртуальные команды ввода-вывода, нужно понять, как файлы организуются и хранятся. Основной вопрос здесь — распределение памяти. Блоком размещения может быть один сектор на диске, но чаще он состоит из нескольких последовательных секторов.
Еще одно фундаментальное свойство файловой системы — то, как располагаются блоки размещения, последовательно или нет. На рис. 6.18 изображен простой диск с одной поверхностью, состоящий из 5 дорожек по 12 секторов каждая. На рисунке 6.18, а файл состоит из последовательных секторов. Последовательное расположение блоков характерно для компакт-дисков. На рис. 6.18, б файл занимает непоследовательные секторы. Такая схема традиционна для жестких дисков.
Восприятие файла прикладным программистом значительно отличается от восприятия файла операционной системой. Программист воспринимает файл как линейную последовательность байтов или логических записей. Операционная система воспринимает файл как упорядоченную, хотя необязательно последовательную, совокупность блоков размещения на диске.
Рис. 6.18. Варианты расположения файла на диске: файл занимает последовательные секторы (а); файл занимает непоследовательные секторы (б)
Для того чтобы операционная система по запросу могла доставить байт или логическую запись п из какого-то файла, она должна пользоваться каким-либо методом для определения местонахождения данных. Если файл расположен последовательно, чтобы вычислить позицию нужного байта или логической записи, операционная система должна знать только место начала файла.
Если файл расположен на диске не последовательно, то лишь по начальной позиции файла невозможно вычислить позицию произвольного байта или логической записи в этом файле. Чтобы найти произвольный байт или логическую запись, нужна таблица, называемая индексом файла и позволяющая получать хранящиеся на диске блоки и их физические адреса. Индекс файла может быть организован либо в виде списка адресов блоков (такая схема используется в UNIX), либо в виде списка логических записей, для каждой из которых даются адрес на диске и смещение. Иногда каждая логическая запись имеет ключ, и программы могут обращаться к записи по этому ключу, а не по номеру логической записи. В последнем случае каждый элемент таблицы должен содержать не только информацию о местонахождении записи на диске, но и ее ключ. Подобная структура обычно применяется в мэйнфреймах.
Альтернативный метод нахождения блоков размещения файла — организовать файл в виде связного списка. В этом случае каждый блок размещения содержит адрес следующего блока. Для реализации этой схемы нужно в основной памяти иметь таблицу со всеми последующими адресами. Например, для диска с 64-килобайтными блоками операционная система может иметь в памяти таблицу из 64 Кбайт элементов, в каждом из которых есть индекс следующего блока размещения. Так, если файл занимает блоки 4, 52 и 19, то элемент 4 в таблице будет содержать число 52, элемент 52 — число 19, а элемент 19 — специальный код, который указывает на конец файла (например, 0 или -1). Так работают файловые системы в MS-DOS, Windows 95 и Windows 98. ОС Windows ХР под держивает эту файловую систему, но имеет также собственную, которая больше похожа на файловую систему UNIX.