МУНИЦИПАЛЬНОЕ БЮДЖЕТНОЕ ОБРАЗОВАТЕЛЬНОЕ УЧРЕЖДЕНИЕ
  ГОРОДА КОСТРОМЫ
"ГИМНАЗИЯ №1"

 

Файлы

 

Файлы. Виды файлов

Файлом называется область памяти жесткого диска, имеющая свое имя.

Число компонент файла может изменяться (увеличиваться или уменьшаться), то есть заранее не фиксируется. Поэтому в них можно хранить достаточно большое количество данных. После каждого элемента автоматически ставится признак конца элемента, а в конце файла ставится признак конца файла.

Один и тот же физический файл можно по-разному представить в программе. Язык Турбо Паскаль предлагает три вида такого представления:

- типизированные файлы,

- текстовые файлы,

- нетипизированные файлы.

И Вы, в зависимости от решаемой задачи, вольны выбирать один их трех видов, а может быть и несколько. Но чтобы определиться, Вы должны хорошо знать не только процедуры и функции, являющиеся общими для всех видов файлов, но и специфичные для каждого вида.

Типизированный файл – последовательность элементов одного типа.

Описание файлового типа имеет синтаксис:

file of < тип элементов>;

Допустим, мы имеем дело с файлом, в котором записываются переменные типа Word, тогда переменная файлового типа может быть введена двояко: с явным объявлением файлового типа:

Type

WordFile = file of word;

Var

MyFile : WordFile

или без объявления файлового типа:

Var

MyFile : file of word

Приведем примеры переменных файлового типа с другими объявлениями.

Type

Student = record

Name, SerName : string;

YearOld : byte;

Sessia : array [1..10] of byte;

end;

Var

VarFile1 : file of char;

VarFile2 : file of Student;

VarFile3 : file of string;

Файловые переменные имеют специфическое применение. Над ними нельзя выполнять никаких операций (присваивать значение, сравнивать и др.). Их можно использовать только для выполнения операций с файлами (чтения, записи, удаления файла и т.д.). кроме того, через файловую переменную можно получить информацию о конкретном файле (тип, параметры, имя файла и т.д.).

С каждым файлом можно связать понятие текущий указатель. Это неявно описанная переменная, которая указывает на конкретный элемент файла. Действия с файлами производятся поэлементно, причем в них участвует тот элемент, на который "смотрит" текущий указатель, перемещающийся в результате выполнения действия на следующий элемент.

Переменные файлового типа используются в программе только в качестве параметра собственных и стандартных процедур и функций. Все фактические действия с файлами основаны на наборе стандартных процедур языка, входящих в состав модулей System и Dos.

Алгоритм работы с файлами

1. До начала работы с файлами устанавливается связь файловой переменной МуFilе с именем дискового файла. Очень важно различать собственно файл (область памяти на магнитном носителе с некоторой информацией) и переменную файлового типа в некоторой Turbo Pascal-программе. Считается, что файловая переменная является представителем некоторого дискового файла в программе. Для того, чтобы реализовать доступ к файлу на магнитном диске, программа должна связать его с файловой переменной. Для этого необходимо сопоставить переменную с именем файла. Это имя представляется в виде строки, содержащей полное имя файла и, может быть, маршрута к файлу, который формируется по общим правилам MS-DOS.

Например,

assign (МуFilе, 'с:\МуDirectory\Result.dat'); - здесь приведено полное (с указанием пути) имя пользовательского файла Result.dat.

Не разрешается связывать с одним физическим файлом различные файловые переменные в программе. Процедура assign не должна использоваться для открытого файла.

До тех пор, пока файловая переменная не связана с каким-либо дисковым файлом, никакие операции с ней в программе невозможны. Заметим, что можно связать файловую переменную с еще не существующим дисковым файлом. Это делается в случае последующего создания Turbo Pascal-программой файла с данным именем с помощью специальной системной процедуры.

2. После того, как файловая переменная с помощью процедуры assign связана с конкретным дисковым файлом, можно выполнить любую допустимую операцию с ним.

Открытие нового файла для записи производится процедурой, единственный аргумент которой – переменная файлового типа, например: rewrite (МуFilе). Следует запомнить, что процедура rewrite обнулит файл, если файл с таким именем уже есть в рабочем каталоге, поэтому при выборе имен файлов соблюдайте осторожность.

Подготовку существующего файла для чтения и записи выполняет процедура reset (МуFilе). Эта процедура ищет уже существующий файл на диске и открывает его для работы, помещая указатель в начальную позицию.

3. Все файлы, открытые в результате работы программы, должны быть закрыты при завершении программы процедурой closе (МуFilе);

При выполнении этого оператора закрывается физический файл на диске и фиксируются изменения, связанные с использованием данного файла. Обратите внимание на необходимость закрытия файлов во всех ветвях программы, в том числе в различных аварийных ситуациях. Незакрытые файлы нарушают файловую структуру на диске, что может приводить к серьезным проблемам с настройкой компьютера.

Запись в файл производится процедурой write (МуFilе, var1, var2, ...., varN). Первый аргумент этой процедуры – переменная файлового типа, далее следует список записываемых переменных, которые должны соответствовать объявленному типу файла. При выполнении этой операции текущий указатель файла смещается на число позиций, равное числу переменных.

Чтение из файла производится аналогичной процедурой: read (МуFilе, var1, var2, ...., varN). Положение элементов в файле нумеруется, начиная с номера 0 для первого элемента. После последнего элемента файла автоматически записывается признак конца файла.

Процедуры и функции для работы с типизированными файлами

Seek (МуFilе, n) – устанавливает текущий указатель в заданную позицию, где n – требуемое положение указателя (нумерация элементов типизированного файла начинается с нуля).Поэтому, чтобы обратиться к третьему элементу, нужно записать Seek (МуFilе, 2). Seek (МуFilе, 0) – устанавливает указатель в начальной позиции (на первый элемент). Seek (МуFilе, FileSize(МуFilе)) – устанавливает указатель после последнего элемента, то есть на признак конца файла.

FileSize (МуFilе) определяет число элементов в файле. Функция FileSize(МуFilе) возвращает количество элементов типизированного файла МуFilе.

FilePos (МуFilе) – определяет текущую позицию указателя.

ЕОF(МуFilе) - имеет значение Тruе, если указатель указывает на маркер конца файла (End Of file).

Процедуры и функции для работы файлами

Rename (МуFilе, FileName) - изменяет имя файла. Первый аргумент – переменная файлового типа, а второй аргумент – строкового типа – новое имя файла, которое может быть сокращенным или полным (с указанием пути).

Truncate (МуFilе) - уничтожение части файла от текущего положения до конца производится процедурой

Erase (МуFilе) - процедура уничтожает весь файл.

Текстовые файлы

Структура текстовых файлов отличается от структуры обычных файлов (которые представляют из себя линейную последовательность элементов одного типа) тем, что содержимое текстового файла рассматривается как последовательность строк переменной длины, разделённых специальной комбинацией, называемой "конец строки". Как правило, эта комбинация строится из управляющего кода "перевода каретки" (CR, Carriage Return, символ #13), за которым, возможно, следует управляющий код "перевод строки" (LF, Line Feed, символ #10). Признаком конца строки считается нажатие клавиши ввода.

Текстовый файл завершается специальным кодом "конец файла" (символ #26). В большинстве случаев знание конкретной кодировки управляющих символов не обязательно ввиду наличия файловых операций, автоматически учитывающих эти символы.

Таким образом, текстовый файл структурно несколько похож на "файл из байтов" (file of byte) с той разницей, что в нем, помимо содержательной информации, встречаются символы специального назначения.

Его можно схематически представить в следующем виде:

. . . . . . . . . . . . . .#13#10

. . . . . . . . . . . . . . . . . . . .#13#10

. . . . . . . . . . . . . . . . .#13#10

. . . . . . . . . . . .#13#10

. . . . . . . . . . . . . . . . . . . . . . . . . .#13#10

#26

Описанная структура текстовых файлов хорошо согласуется с интуитивно понимаемым построением текстовой информации и полностью совпадает со стандартной структурой текстов, принятой в MS-DOS, используемой во многих текстовых редакторах, понимаемой компиляторами с языков программирования и т.д.

С каждым файлом на диске должна быть связана файловая переменная, которая описывается в соответствии с типом файла на диске. Представителем же текстового файла в Pascal-программе является переменная файлового типа, которая должна быть описана с указанием стандартного типа text:

Var

TextFile : text;

Слово text не является зарезервированным словом, а считается идентификатором стандартного типа, наряду с идентификаторами integer, real и т.д.

Ввод-вывод для текстовых файлов подчиняется тем же общим правилам, что и для обычных типизированных файлов; однако имеется несколько важных особенностей.

Во-первых, для одного текстового файла нельзя одновременно производить операции и ввода, и вывода. Это означает, что после открытия текстового файла процедурой reset возможно только чтение информации из файла, после процедуры rewrite – только запись в файл.

Во-вторых, обмены с текстовыми файлами всегда являются строго последовательными, то есть после чтения из файла элемента с порядковым номером N следующая операция чтения даст элемент с номером N+1. Иными словами, прямой доступ к любому элементу текстового файла невозможен; для текстовых файлов не допускаются вызовы Seek, FilePos, FileSize.

В третьих, еще одной особенностью работы с текстовыми файлами является возможность непосредственных обменов значениями различных базовых типов (для обычных типизированных файлов тип параметров read и write должен совпадать с базовым типом файла). Так, в текстовый файл можно записать6 например, целое или вещественное число. При этом его внутреннее представление будет автоматически преобразовано в строчку символов, образующих изображение этого числа.

Для работы с текстовыми файлами, помимо основных процедур и функций, используются и дополнительные.

Процедуры и функции для работы с текстовыми файлами

Eoln (MyFile) функция, для обработки текстовых файлов, позволяющая определить достигнут ли конец строки. Если достигнут – значение функции равно True, а если нет – False. Таким образом, для анализа конкретных символов строк файла можно применить вложенный цикл типа:

while not Eof(NameFale) do {пока нет конца файла NameFale делай}

while not Eoln(NameFale) do {пока нет конца строки файла NameFale делай}

begin

{группа операторов обработки символов очередной строки}

end;

Append (MyFile : Тext) – процедура открывает существующий файл для присоединения. Если файл уже открыт, то он сначала закрывается, а затем открывается заново. Текущая позиция устанавливается на конец файла. Если в последнем блоке файла размером 128 байтов присутствует символ Сtrl+Z (26 в коде ASCII), то текущая позиция устанавливается в файле таким образом, что при записи первым в блоке будет "затираться" символ Сtrl+Z. После обращения к append файл MyFile становится доступным только по записи и Eof(MyFile) принимает всегда значение True(истина).

Нетипизированные файлы

Нетипизированные файлы – это файлы, поддержка которых осуществляется с максимально возможной скоростью. Введение таких файлов в систему Турбо Паскаль было вызвано стремлением повысить эффективность программ, участвующих в интенсивном обмене с внешними наборами данных.

Эти файлы в отличие от уже рассмотренных не имеют строго определенного типа. Нетипизированный файл рассматривается в Паскале как совокупность символов или байтов. Представление char или byte не играет никакой роли, важен лишь объем занимаемых данных. Такое представление стирает различия между файлами независимо от типа их объявления. На практике это приводит к тому, что любой файл, подготовленный как текстовый или типизированный, можно открыть и начать работу с ним, как с нетипизированным набором данных.

Для определения в программе нетипизированного файла служит зарезервированное слово file:

Var

MyFile : file;

Внутренняя поддержка таких файлов выглядит наиболее близкой к аппаратной поддержке работы с внешними носителями. За счет этого достигается максимально возможная скорость доступа к наборам данных. Для нетипизированных файлов не нужно терять время на преобразование типов и поиск управляющих последовательностей, достаточно считать содержимое файла в определенную область памяти.

Нетипизированный файл является файлом прямого доступа, что говорит о возможности одновременного использования операций чтения и записи.

Для таких файлов самым важным параметром является длина записи в байтах. Открытие нетипизированного файла с длиной записи в 1 байт можно выполнить следующим образом:

rewrite(MyFile, 1) или reset(MyFile, 1)

Второй параметр, предназначенный только для использования с нетипизированными файлами, задает длину записи файла на сеанс работы.

Особенность аппаратной поддержки заключается в том, что при обращении к внешнему устройству минимально возможным объемом для считывания являются 128 байт. В стремлении добиться наибольшей эффективности файловых операций в Турбо Паскале принято соглашение, по которому длина записи нетипизированного файла по умолчанию составляет 128 байт. Поэтому после открытия файла с помощью вызовов: rewrite(MyFile) или reset(MyFile) все процедуры и функции, обслуживающие файлы прямого доступа, работают с записями длиной 128 байт. Каждый пользователь для своих программ может выбрать наиболее подходящий размер записи.

Турбо Паскаль не накладывает каких-либо ограничений на длину записи нетипизированного файла, за исключением требования положительности и ограничения максимальной длины 65535 байтами (емкость целого типа word). Для того, чтобы гарантированно обеспечить полное чтение всего файла, рекомендуется установить размер записи равным 1.

При работе с нетипизированными файлами могут применяться все процедуры и функции, доступные типизированным файлам. Но так же имеются процедуры, которые доступны только для нетипизированных файлов: BlockRead, BlockWrite.

Процедура BlockRead

Формат обращения:

blockread(Var F : file; Var Buf; Kolblocks : word; result : word);

Процедура считывает из файла F определенное число блоков в память, начиная с первого байта переменной Buf.

Параметр Buf представляет любую переменную, которая будет участвовать в обмене данными с дисками. Эту переменную нужно описать в программе так, чтобы ее размер не был меньше размера записи, установленного в параметрах rewrite или reset (как правило, для этих целей используется некоторый массив).

Параметр Kolblocks задает число считываемых блоков, которые должны быть прочитаны за одно обращение к диску.

Параметр result является необязательным и содержит после вызова процедуры число действительно считанных записей.

Использование параметра result подсказывает, что число считанных блоков может быть меньше, чем задано параметром Kolblocks. Если result указан при вызове, то ошибки ввода-вывода в такой ситуации не произойдет. Для отслеживания этой и других ошибок чтения можно использовать опции {$I-}, {$I+} и функцию IOresult.

Кроме того, что переменная F должна быть описана как нетипизированный файл, она должна быть связана с конкретным физическим диском процедурой assign. Файл должен быть открыт процедурой reset.

Процедура BlockWrite

Формат обращения:

blockwrite(Var F : file; Var Buf; Kolblocks : word; result : word);

Процедура предназначена для быстрой передачи в файл F определенного числа записей из переменной Buf. Все параметры процедуры blockwrite аналогичны параметрам процедуры blockread. Разница лишь в том, что файл должне быть подготовлен для записи процедурой rewrite. Содержимое переменной Buf целиком помещается в файл, начиная с текущей записи.

Обе процедуры выполняют операции ввода-вывода блоками. Объем блока в байтах определяется по формуле: Объем = Kolblocks * recSize, где recSize – размер записи файла, заданный при его открытии. Суммарный объем разового обмена не должен превышать 64 Кбайт. Помимо скорости передачи данных преимущество этих процедур заключается в возможности пользователя самостоятельно определять размер буфера для файловых операций. Эта возможность играет значительную роль в тех задачах, где необходимо жесткое планирование ресурсов. Программист должен позаботиться о том, чтобы длина внутреннего представления переменной Buf была достаточной для размещения всех байт при чтении информации с диска.

Дело в том, что чтение информации из файла в буфер, равно как и запись из буфера в файл, производится без типового контроля. Поэтому несоблюдение указанного условия может привести к порче соседних с буфером данных или к помещению на файл посторонней информации.

Если при чтении указана переменная Buf недостаточной длины или если в процессе записи на диск не окажется нужного свободного пространства, то произойдет следующее. Если последний параметр result в этих вызовах не задан, то возникает ошибка ввода-вывода; если параметр result задан, то ошибка не будет зафиксирована, а после выполнения процедуры его значение не будет совпадать с значением параметра Kolblocks. Последнее обстоятельство можно проверить, сравнив два указанных значения. После завершения процедуры указатель смещается на result записей.

НАЦИОНАЛЬНЫЙ ФОНД ПОДГОТОВКИ КАДРОВ. ИНФОРМАТИЗАЦИЯ СИСТЕМЫ ОБРАЗОВАНИЯ.
Сайт сделан по технологии "Конструктор школьных сайтов".