Глава 6a (1085729), страница 2
Текст из файла (страница 2)
Большим преимуществом ASCII-файлов является то, что они могут отображаться на экране и выводиться на печать так, как есть, без какого-либо преобразования, и могут редактироваться практически любым текстовым редактором. Более того, если большое количество программ использует ASCII-файлы для входа и выхода, то оказывается несложным соединить вход одной программы с выходом другой, как это делается в конвейерах оболочки. (Обмен данными между процессами при этом не становится проще, но интерпретация информации облегчается, если для ее выражения применяется стандарт, такой как ASCII.)
Остальные файлы называются двоичными, то есть они не являются ASCII-файлами. При выводе их на принтер получается невразумительный набор символов, напоминающий случайный мусор. Обычно у них есть некая внутренняя структура, известная программе, использующей их.
Например, на рис. 6.2, а показан простой исполняемый двоичный файл одной из версий системы UNIX. Хотя технически файл представляет собой всего лишь последовательность байтов, операционная система станет исполнять файл только в том случае, если этот файл имеет соответствующий формат. Файл состоит из пяти разделов: заголовка, текста, данных, релокационных битов и таблицы символов. Заголовок начинается с так называемого «магического» числа, идентифицирующего файл как исполняемый (чтобы предотвратить случайное исполнение файла другого формата). Следом за «магическим» числом в заголовке располагаются размеры различных частей файла, адрес начала исполнения файла и некоторые флаговые биты. За заголовком следуют текст программы и данные. Они загружаются в оперативную память и настраиваются на работу по адресу загрузки при помощи битов релокации. Таблица символов используется для отладки.
Рис. 6.2. Исполняемый файл (а); архив (б)
Второй пример двоичного файла представляет собой файл архива, также из системы UNIX. On состоит из набора библиотечных процедур (модулей), откомпилированных, но не скомпонованных. Каждой процедуре предшествует заголовок, содержащий ее имя, дату создания, владельца, код защиты и размер. Как и в случае исполняемого файла, заголовки модулей содержат большое количество двоичных чисел. Если скопировать их па принтер, получится полная тарабарщина.
Все операционные системы должны распознавать по крайней мере один тип файлов — свои собственные исполняемые файлы, по некоторые операционные системы распознают и другие типы файлов. Старая система TOPS-20 (для компьютера DECsystem 20) даже изучала время создания каждого предоставляемого ей на исполнение файла. Затем она находила исходный файл и проверяла, не был ли он изменен, после того как был создан исполняемый файл. Если оказывалось, что исполняемый файл уже устарел, операционная система автоматически перекомпилировала исходный файл. Если перевести это па язык понятий UNIX, то это означало, что программа make была встроена в оболочку. Расширения файлов были обязательными, чтобы операционная система могла определить, какая двоичная программа от какого исходного файла произошла.
Однако такая жесткая заданность типов файлов может оказаться неудобной для пользователя, пытающегося сделать что-нибудь, не предусмотренное проектировщиками операционной системы. Представьте, например, систему, в которой файлы программного вывода автоматически получают расширение .dat (файлы данных). Пусть пользователь написал программу, форматирующую исходные тексты программ на С. Эта программа читает файл с расширением .с, обрабатывает его и затем пишет результат в файл со стандартным расширением .dat. Если пользователь затем попытается предложить этот файл С-компилятору, операционная система пе даст этого сделать, так как у файла для данного действия неверное расширение. Попытка скопировать file.dat в file.с также будет отвергнута операционной системой.
Хотя такая «дружественность» по отношению к пользователю (защищающая пользователя от ошибок) может быть полезна для новичков, она ставит опытных пользователей в безвыходное положение, заставляя их тратить массу усилий на попытки перехитрить операционную систему.
Доступ к файлам
В старых операционных системах предоставлялся только один тип доступа к файлам — последовательный доступ. В этих системах процесс мог читать байты или записи файла только по порядку от начала к концу. Такой доступ к файлам появился, когда дисков еще не было и компьютеры оснащались магнитофонами. Поэтому даже в дисковых операционных системах при последовательном доступе к файлу имитировалось его чтение или запись на накопителе на магнитной ленте с возможностью многократной перемотки назад.
С появлением дисков стало возможным читать байты или записи файла в произвольном порядке или получать доступ к записям по ключу. Файлы, байты которых могут быть прочитаны в произвольном порядке, называются файлами произвольного доступа. Такие файлы используются многими приложениями.
Файлы произвольного доступа очень важны для многих приложений, например для баз данных. Если клиент звонит в авиакомпанию с целью зарезервировать место на конкретный рейс, программа резервирования авиабилетов должна иметь возможность получить доступ к нужной записи, не читая все тысячи предшествующих записей, содержащих информацию о других рейсах.
Для указания места начала чтения используются два метода. В первом случае каждая операция read задает позицию в файле. При втором способе используется специальная операция поиска seek, устанавливающая текущую позицию. После выполнения операции seek файл может читаться последовательно с текущей позиции.
В некоторых старых операционных системах, использовавшихся на мэйнфреймах, способ доступа к файлу (последовательный или произвольный) указывался в момент создания файла. Это позволяло операционной системе применять различные методы для хранения файлов разных классов. В современных операционных системах такого различия не проводится. Все файлы автоматически являются файлами произвольного доступа.
Атрибуты файла
У каждого файла есть имя и данные. Помимо этого все операционные системы связывают с каждым файлом также и другую информацию, например дату и время создания файла, а также его размер. Мы будем называть эти дополнительные сведения атрибутами файла. Список атрибутов значительно варьируется от системы к системе. В табл. 6.2 показаны некоторые возможные атрибуты, однако существуют также и другие возможности. Ни в одной существующей операционной системе не присутствуют сразу все приведенные в таблице атрибуты файлов, но каждый из них используется в той или иной системе.
Таблица 6.2. Некоторые возможные атрибуты файлов
Атрибут Значение
Защита Кто и каким образом может получить доступ к файлу
Пароль Пароль для получения доступа к файлу
Создатель Идентификатор пользователя, создавшего файл
Владелец Текущий владелец
Флаг «только чтение» 0 — для чтения/записи; 1 — только для чтения
Флаг «скрытый» 0 — нормальный; 1 —- не показывать в перечне файлов каталога
Флаг «системный» 0 — нормальный; 1 — системный
Флаг «архивный» 0 — заархивирован; 1 — требуется архивация
Флаг ASCII/двоичный 0 —ASCII; 1 —двоичный
Флаг произвольного доступа 0 — только последовательный доступ; 1 — произвольный доступ
Флаг «временный» 0 — нормальный; 1 — для удаления файла по окончании работы процесса
Флаги блокировки 0 — неблокированный; отличный от нуля для блокированного
Длина записи Количество байтов в записи.
Позиция ключа Смещение до ключа в записи
Длина ключа Количество байтов в поле ключа
Время создания Дата и время создания файла
Время последнего доступа Дата и время последнего доступа файла
Время последнего изменения Дата и время последнего изменения файла
Текущий размер Количество байтов в файле
Максимальный размер Количество байтов, до которого можно увеличивать размер файла
Первые четыре атрибута относятся к защите файла и содержат информацию о том, кто может получить доступ к файлу, а кто нет. Возможны различные схемы реализации защиты файла, несколько из них мы рассмотрим ниже. В некоторых системах пользователь должен для получения доступа к файлу указать пароль. В этом случае пароль должен входить в атрибуты файла.
Флаги представляют собой биты или короткие поля, управляющие некоторыми специфическими свойствами. Например, скрытые файлы не появляются в перечне файлов при распечатке каталога. Флаг архивации представляет собой бит, следящий за тем, была ли создана для файла резервная копия. Этот флаг очищается программой архивирования и устанавливается операционной системой при изменении файла. Таким образом программа архивирования может определить, какие файлы следует архивировать. Флаг «временный» позволяет автоматически удалять помеченный так файл по окончании работы создавшего его процесса.
Атрибуты длина записи, позиция ключа и длина ключа присутствуют только у тех файлов, записи которых могут искаться по ключу. Эти атрибуты предоставляют необходимую для поиска ключа информацию.
Различные атрибуты, хранящие значения времени, позволяют следить за тем, когда файл был создан, в последний раз изменен и когда к нему в последний раз предоставлялся доступ. Эти сведения можно использовать в различных целях. Например, если исходный файл программы был модифицирован после создания соответствующего ему объектного файла, то исходный файл должен быть перекомпилирован.
Текущий размер файла содержит количество байтов в файле в настоящий момент. В некоторых старых операционных системах, использовавшихся на мэйнфреймах, при создании файла требовалось указать также максимальную длину файла, что позволяло операционной системе зарезервировать достаточно места для последующего увеличения файла. Современные операционные системы, работающие на персональных компьютерах и рабочих станциях, умеют обходиться без подобного резервирования.
Операции с файлами
Файлы позволяют сохранять информацию и получать ее позднее. В различных операционных системах имеются различные наборы файловых операций. Ниже мы перечислим наиболее часто встречающиеся системные вызовы, относящиеся к файлам.
-
Create (создание). Файл создается без данных. Этот системный вызов объявляет о появлении нового файла и позволяет установить некоторые его атрибуты.
-
Delete (удаление). Когда файл уже более не нужен, его удаляют, чтобы освободить пространство на диске. Этот системный вызов присутствует в каждой операционной системе.
-
Open (открытие). Прежде чем использовать файл, процесс должен его открыть. Системный вызов open позволяет системе прочитать в оперативную память атрибуты файла и список дисковых адресов для быстрого доступа к содержимому файла при последующих вызовах.
-
Close (закрытие). Когда все операции с файлом закончены, атрибуты и дисковые адреса более не нужны, поэтому файл следует закрыть, чтобы освободить пространство во внутренней таблице. Многие операционные системы позволяют одновременно открыть ограниченное количество
файлов. Запись на диск производится поблочно, а закрытие файла вызывает запись последнего блока файла, даже если этот блок еще не заполнен до конца. -
Read (чтение). Чтение данных из файла. Обычно байты поступают с текущей позиции в файле. Вызывающий процесс должен указать количество требуемых данных и предоставить для них буфер.
-
Write (запись). Запись данных в файл, также в текущую позицию в файле. Если текущая позиция находится в конце файла, размер файла автоматически увеличивается. В противном случае запись производится поверх существующих данных, которые теряются навсегда.
-
Append (добавление). Этот системный вызов представляет собой усеченную форму вызова write. Он может только добавлять данные к концу файла. В операционных системах с минимальным набором системных вызовов может не быть данного системного вызова.
-
Seek (поиск). Для файлов произвольного доступа требуется способ указать, где располагаются данные в файле. Данный системный вызов устанавливает файловый указатель в определенную позицию в файле. После выполнения данного системного вызова данные могут читаться или записываться в этой позиции.
-
Get attributes (получение атрибутов). Процессам часто для выполнения их работы бывает необходимо получить атрибуты файла. Например, для сборки программ, состоящих из большого числа отдельных исходных файлов, в системе UNIX часто используется программа make. Эта программа исследует время изменения всех исходных и объектных файлов, благодаря чему обходится компиляцией минимального количества файлов. Для выполнения этой работы ей требуется получить атрибуты файлов.
-
Set attributes (установка атрибутов). Некоторые атрибуты файла могут устанавливаться пользователем после создания файла. Этот системный вызов предоставляет такую возможность. Например, для файла может быть установлен код защиты доступа. Большинство других флагов также могут устанавливаться при помощи данного системного вызова.
-
Rename (переименование). Этот системный вызов позволяет изменить имя файла. Его присутствие в операционной системе не является необходимым, так как обычно файл можно скопировать с новым именем, а старый файл удалить.