Работа с файлами в MS-DOS. Хэндлы. Внутренние структуры данных подсистемы управления данными (SFT, JFT)
Работа с файлами в MS-DOS. Системные функции.
Для работы с файлами и каталогами системы FAT в MS-DOS предусмотрен достаточно богатый набор функций. Все они вызываются с помощью команды программного прерывания int 21h, а конкретная функция определяется числом, занесенным в регистр AH. Эти функции позволяют, в частности:
создавать файл, указывая его полное имя;
удалять файл;
изменять атрибуты файла;
переименовывать файл или перемещать его в другой каталог того же диска;
искать в заданном каталоге все файлы, имена которых соответствуют заданному шаблону (например, шаблону «XYZ??.C*» соответствуют все файлы, имена которых начинаются с «XYZ» и содержат ровно 5 символов, а расширение начинается с буквы «C»);
создавать и удалять каталоги;
задавать текущий диск и текущий каталог;
открывать файл, получая доступ к его данным, и закрывать файл.
Доступ к данным
В MS-DOS существует два различных набора функций, позволяющих работать с данными файлов. Один из них, основанный на использовании блока управления файлом (FCB), вряд ли кем-то использовался в последние 20 лет, однако сохраняется из соображений совместимости с версией MS-DOS 1.0. Общепринятый метод работы с файлами основан на использовании хэндлов.
Чтобы открыть существующий файл, следует вызвать соответствующую функцию, указав в качестве параметров имя файла и желаемый режим доступа (один из трех: только чтение, только запись, чтение и запись). В более поздних версиях MS-DOS появилась также возможность указывать режим разделения. Любой файл рассматривается как последовательность байт, а если программа предпочитает рассматривать файл как набор записей, то она должна сама вести пересчет номера записи в смещение (в байтах) от начала файла. Операции чтения и записи всегда выполняются от текущей позиции, которая называется указателем чтения/записи, и приводят к смещению указателя вперед на прочитанное или записанное количество байт. Возможность произвольного доступа к данным обеспечивается операциями перемещения указателя.
Хэндл — это некоторое число, которое система возвращает пользовательской программе при удачном выполнении операции открытия или создания файла. Значение этого числа не играет роли для программы. Важно лишь то, что при последующих обращениях к открытому файлу программа должна передавать этот хэндл системе как указатель на этот файл.
MS-DOS предоставляет вполне достаточный набор функций для работы с открытыми файлами. Сюда включаются функции чтения и записи произвольного числа байт, функция перемещения указателя в произвольную точку файла, функции установки и снятия блокировки фрагментов файла, принудительной очистки кэш-буферов файла (обычно очистка выполняется только при закрытии файла или при нехватке буферов; принудительная очистка гарантирует немедленное сохранение изменений на диске).
При вызове функции открытия файла можно вместо имени файла указать имя любого символьного устройства, например, «PRN:». При этом также возвращается хэндл, с которым можно выполнять операции записи так же, как если бы этот хэндл указывал на дисковый файл. Разумеется, нельзя открыть принтер для чтения, а также нельзя выполнять перемещение указателя назад.
При запуске любой программы она получает «в подарок» от MS-DOS пять уже открытых хэндлов с номерами от 0 до 4. Из них наиболее важными являются хэндл 0, который по определению указывает на стандартный ввод программы, и хэндл 1 — стандартный вывод. Хэндл 2 означает стандартное устройство для вывода сообщений об ошибках, хэндл 3 — стандартное устройство последовательного ввода/вывода (COM-порт), хэндл 4 — стандартный принтер.
Компиляторы языков программирования, встречая вызовы процедур ввода/вывода без указания файла, транслируют их в вызовы системных функций MS-DOS с хэндлами, соответственно, 0 или 1.
Если программа запускается из командной строки MS-DOS, то обычно хэндл 0 указывает на клавиатуру (точнее, на устройство CON:), а хэндл 1 — на экран монитора (тоже устройство CON:, но работающее на вывод). Однако пользователь может использовать символы перенаправления стандартного ввода (знак «<») и вывода (знаки «>» и «>>»). Например, программа, запущенная при помощи команды «MY_PROG <INFILE.TXT >PRN» будет использовать в качестве стандартного ввода файл INFILE.TXT, а стандартный вывод направит на принтер. Знак «>>» означает добавление данных в конец файла стандартного вывода, знак «>» — перезапись файла заново. Чтобы выполнить указанное пользователем перенаправление стандартного ввода или вывода, система открывает заданный файл или устройство (а при знаке «>>» еще и выполняет перемещение указателя в конец файла) и обеспечивает доступ к нему из запускаемой программы через стандартный хэндл 0 или 1. Таким образом, работающая программа вообще не знает, какие именно устройства или файлы являются ее стандартным вводом и выводом.
Перенаправление стандартного ввода и вывода может быть выполнено и программой пользователя. Обычно это делается перед тем, как данная программа запускает какую-либо другую программу, передавая ей перенаправленные стандартные хэндлы.
Структуры данных в памяти
Для обеспечения доступа к открытым файлам MS-DOS использует системные таблицы двух типов.
Таблица SFT (System File Table) содержит записи о всех файлах, в данный момент открытых программами пользователя и самой ОС. Эта таблица хранится в системной памяти, число записей в ней определяется параметром FILES в файле конфигурации CONFIG.SYS, но не может превышать 255.
Если один и тот же файл был открыт несколько раз (неважно, одной и той же программ ой или разными программами), то для него будет несколько записей в SFT.
Каждая запись содержит подробную информацию о файле, достаточную для выполнения операций с ним. В частности, в записи SFT содержатся:
копия каталожной информации о файле;
адрес каталожной записи (сектор и номер записи в секторе);
текущее положение указателя чтения/записи;
номер последнего записанного или прочитанного кластера файла;
адрес в памяти программы, открывшей файл;
режим доступа, заданный при открытии.
Кроме того, в записи SFT содержится значение счетчика ссылок на данную запись из всех таблиц JFT, речь о которых пойдет ниже. Когда этот счетчик становится равным нулю, запись SFT становится свободной, поскольку файл закрыт.
В отличие от единственной SFT, таблицы JFT (Job File Table) создаются для каждой запускаемой программы, поэтому одновременно может существовать несколько таких таблиц. (А откуда в однозадачной MS-DOS могут взяться одновременно несколько программ? Простейший ответ: когда одна программа запускает другую, то в памяти присутствуют обе). Таблица JFT имеет простейшую структуру: она состоит из однобайтовых записей, причем значение каждой записи представляет собой индекс (номер записи) в таблице SFT. Неиспользуемые записи содержат значение FF16. Размер таблицы по умолчанию составляет 20 записей (байт), но может быть увеличен до 255.
Теперь о хэндлах. Прикладная программа использует хэндлы как некоторые условные номера открытых файлов, конкретное значение хэндла при этом не играет никакой роли (за понятным исключением стандартных хэндлов с 0 по 4). На самом же деле значение хэндла представляет собой не что иное, как индекс записи в таблице JFT данной программы. Первая запись таблицы соответствует хэндлу 0.