Т. Пратт, М. Зелковиц - Языки программирования - разработка и реализация (4-е издание_ 2002) (1160801), страница 64
Текст из файла (страница 64)
'1 см не менее для явного изменения режима доступа к файлу (от записи к чтению и наоборот) его следует закрь<ть явным образом и потом открыть в требуемом режиме. 226 Глава 5. Элементарные типы данных Реализация. В большинстве компьютерных систем использусмая операционная система отвстствснна за реализацию файлов, поскольку они создаются и обрабатываются различными языковыми процессорами и утилитами. Операции над файлами в основном реализованы с использованием элементарных команд, прсдоставлясмых операционной системой. Обычные программные 'Г::::Л переменные Передача блоками БУФЕР ДЛЯ ФАЙЛА Рнс.
Б.б. Реализация файла с использованием буфера С точки зрения языка основная проблема при реализации файлов заключается в выделении памяти для системных данных и буфсров, которые используются элементарными системными командами, Обычно, когда в процессе выполнения программы открывается какой-нибудь файл, в памяти отводится место для буферов и таблицы, содсржащсй информацию о файле.
Элсмснтарная команда открытия файла операционной системы сохраняет в этой таблице информацию о местоположении и других характеристиках файла. Предположим, файл открыт в режиме записи. Когда операция записи псрссыласт компонспт, который должен быть добавлен в конец файла, его данные в дсйствитсльности пересылаются элементарной системной команде записи, которая сохраняет их в следующей доступной позиции в буфере, расположснном в памяти компьютера, и измсняст указатели ца этот буфер в таблице файловой информации. Никакой фактической передачи данных в файл нс происходит до тех пор, пока нс будет выполнено достаточное количество операций записи, чтобы полностью заполнить блок компонентов в буфере. После этого весь блок компонентов передается из буфера на внешнее запомн наю- 5.3.
Составные типы данных 227 щее устройство (например, диск или магнитную ленту). Следующая последовательность выполняемых в процессе работы программы операций записи вновь заполняет буфер до тех пор, пока снова полностью не заполнится его блок компонентов, готовый к передаче на внешнее запоминающее устройство. При считывании файла происходит обратный процесс: данные передаются из файла в буфер в виде бюльших блоков компонентов, а затем каждая операция чтения, выполняемая программой, передает по одному компоненту из буфера в программную переменную. По мере надооности буфер заполняется снова.
Эта организация процесса чтения- записи в последовательный файл проиллюстрирована схемой на рис. 5.6. Текстовые файлы Текстовьш' фийл (английский термин гезт<11е заимствован из языка Рааса)) — это файл, состоящий из символов. Текстовые файлы являются основной формой файлов, используемых пользователем для ввода и вывода данных в большинстве языков программирован<и, так как они могут быть непосредственно распечатаны или введены с клавиатуры. Файлы, содержащие компоненты другого типа, обычно могут быть использованы только для записи и чтения из программы.
Текстовые файлы — это всего лишь одна из форм обычных последовательных файлов, и с ними можно производить те же действия, что и с последовательными файлами. Но часто для них определены специальные операции, которые позволяют при вводе автоматически преобразовывать числовые данные (и иногда данные других типов) из символьного вида в их внутреннее представление, используемое при хранении в памяти. Аналогичные операции при выводе позволяют преобразовывать данные из внутреннего представления в символьную форму, Вместе с этими преобразованиями обычно обеспечивается возможность форматирования выводимых данных— разбиение на строки определенной длины с подходящим размещением заголовков, пробелов, интервалов и преобразованием элементов данных к виду, который желателен при печати выводимых данных.
Этот выходной формат является важной частью реализации операций вывода для текстовых файлов. Аналогичные операции форматирования могут использоваться при вводе либо ввод может осуществляться в свобо<)нем формате — когда числа, разделенные пробелами, располагаются в любом месте строки ввода.
В этом случае операция чтения сканирует строку (или строки) ввода и находит требуемые для удовлетворения запроса на чтение числа. Интерактивный ввод-вывод Рассмотрим текстовый файл, ассоциированный с интерактивным терминалом, за которым работает программист. При выполнении программы операция записи из этого файла интерпретируется как команда отображения символов на экране терминала. Операция чтения соответственно представляет команду, которая выполняет запрос на ввод данных с клавиатуры, начало которой обычно характеризуется отображением на экране специального символа-приглашения на ввод данных.
При таких установках некоторые аспекты обычной интерпретации последовательных файлов, описанные ранее, несколько изменяются. 1. Файл должен быть открыт одновременно в режиме и записи, и чтения, так как обычные операции чтения и записи при интерактивном вводе-выводе 228 Глава 5.
Элементарные типы данных чередуются. Сначала какие то данные отображаются на экране затем какието данные ввода запрашиваются и т, д. 2. Буферизация данных операций ввода и вывода ограничена. Во входном буфорс редко может накопиться больше одной строки данных, подлежащих обработке, Данные, собранные в выходном буфере, должны быть отображены на экране, прежде чем будет сделан запрос на чтение с терминала. 3.
Указатель текущей позиции в файле и проверка конца файла имеют сравнительно небольшое значение. В интерактивном файле отсутствует понятие позиции в том смысле, который обсуждался выше, и у него нет конца, так как программист может продолжать ввод данных неограниченно. Правда, он может использовать специальный управляющий символ, означающий конец ввода с терминала определенной порции входных данных, но обычные представления о проверке конца файла и о завершении процесса обработки файла здесь неприменимы.
Из-за этих существенных различий между интерактивными файлами и обычными последовательными файлами во многих языках возникают проблемы при внсдрении интерактивных файлов в структуру ввода-вывода, предназначенную для обычных последовательных файлов'. Файлы прямого доступа В последовательном файле доступ к компонентам должен осуществляться последовательно в порядке их расположения в файле. Хотя обычно имеется некоторый ограниченный набор операций, позволяющий переместить указатель текущей позиции в файле вперед или назад, все же непосредственный доступ к произвольному компоненту, как правило, невозможен'.
Файл прямого доступа, напротив, организован так, что возможен доступ к произвольному компоненту файла так жс, как, например, осуществляется доступ к элементам массивов или записей. Индекс, используемый для доступа к компоненту, обычно называется ключом и может быть нли целым числом, илп каким-нибудь другим идентификатором. Если ключ реализован в виде целого числа, то он очень похож на обычный индекс, используемый душ обозначения компонентов массива. Однако в целом реализация файла прямого доступа и операций выбора ого компонентов сильно отличается от реализации массива, так как файлы хранятся не в основной памяти, а на вторичных устройствах хранения информации. Файл прямого доступа реализован как неупорядоченный набор компонентов, с каждым из которых ассоциировано собственное ключевое значение. Исходно файл пуст, и его заполнение осуществляется при помощи операции записи, которой в качестве параметров передастся компонент, содержимое которого копирует- В совреыенных интерактивных языках программирования файлы ввола с клавиатуры и вывода на экран монитора реализонаны как два самостоятельных файла, например, в С стандартные файлы ввода ьмщ и вывода ьмовк в Рег! соответственно 5ТО1Н и буэээу и т.
д. — Примеч, науч, ред. Здесь важен непосредственный поступ, так как в последовательном файле можно получить доступ к лвбому компоненту, но для этого обычно следует каждый раз устанавливать указатель текущей позиции файла на его начало, а далыне последователыю читать компоиенты, пропуская ненужные, пока не будет востигнут требуемый компонент.
— Правее. науч. Ред. 5.4. Обзор языка ГОЯТНАМ 229 ся в файл, и ключевое значение, ассоциированное с этим компонентом. Операция записи создает новый компонент на внешнем запоминающем устройстве и копирует в него значение переданного ей в качестве параметра компонента. Ключевое значение обычно ассоциируется с местоположением на внешнем запоминающем устройстве созданного компонента путем сохранения пары (ключ, местоположение) в индексе — векторе, содержащем подобные пары.
Каждая операция записи, которая записывает компонент файла с новым ключевым значением, добавляет в индекс новую пару. Но если команда записи в качестве аргумента получает значение ключа уже существующего компонента, то содержимое старого компонента заменяется значением компонента, переданного ей в качестве аргумента. Таким образом, запись в файл прямого доступа аналогична присвоению некоторого значения компоненту вектора, где значение ключа является индексом. Операция чтения в качестве аргумента получает значение ключа компонента. Затем просматривается индекс и отыскивается пара с таким значением ключа, после чего компонент читается из указанного в паре его местоположения на внешнем запоминающем устройстве.
Индексно-последовательные файлы Индексно-последовательный файл похож на файл прямого доступа, с тем лишь отличием, что для него предусмотрена дополнительная возможность последовательного доступа к компонентам, начиная с произвольно выбранного. Допустим, например, что для операции чтения выбран компонент, значение ключа у которого равно 27. Тогда последующая операция чтения может выбрать следующий за ним компонент, причем уже не требуется указывать значение ключа.