Автор: Пользователь скрыл имя, 28 Декабря 2011 в 12:54, реферат
Надо заметить, что физически единой эта область данных вовсе не является: файл обычно состоит из целого набора так называемых кластеров (участков диска фиксированного для операционной системы размера), которые разбросаны по диску тем прихотливее, чем чаще мы стираем и записываем на него информацию.
Вообще, система окажется наиболее производительной, если кластеры файла будут идти не подряд, а с неким постоянным интервалом: пока система "переварит" данные с одного кластера, диск как раз успеет повернуться до другого.
Работа с файлами данных в Паскале
1. Физические и логические файлы. Типы файловых переменных.
Физическим файлом мы называем единую именованную область данных на диске. Физический файл определяется строкой с его именем и путем к нему.
Например:
Надо заметить,
что физически единой эта область
данных вовсе не является: файл обычно
состоит из целого набора так называемых
кластеров (участков диска фиксированного
для операционной системы размера),
которые разбросаны по диску тем
прихотливее, чем чаще мы стираем
и записываем на него информацию.
Вообще, система окажется наиболее производительной,
если кластеры файла будут идти не подряд,
а с неким постоянным интервалом: пока
система "переварит" данные с одного
кластера, диск как раз успеет повернуться
до другого.
Для того, чтобы упорядочить (еще говорят,
дефрагментировать) информацию на диске,
используют специальные утилиты-дефрагментаторы.
Одна из таких входит в поставку Windows.
Расширения указывают на тип файлов, при пользовательской работе мы четко различаем их.
Например, файл tet.exe является исполняемым модулем, а myprog.pas - очевидно, текстом программы на языке Паскаль.
Однако, как мы увидим дальше, в программировании таких четких различий для файлов данных не существует, если мы сами их не задаем. Файлы данных, с которыми мы будем работать, могут иметь любое расширение, например, ".dat" для исходных данные и ".res" для файла результатов.
С точки зрения программирования все файлы можно разделить на две группы:
Логический файл в Паскале описывается как переменная одного из файловых типов.
Мы связываем логический файл с физическим файлом на диске и через логический получаем доступ к физическому. В результате, как мы скоро увидим, нам не нужно задумываться о технических проблемах, чтобы организовать обмен данными между нашей программой и файлом.
В Паскале существует три типа файловых переменных:
Текстовый файл, с которым мы работаем в DOS-среде, состоит из последовательности ASCII-кодов, среди которых могут быть и управляющие.
Байты текстового файла организуются по строкам. Информацию любого типа (числовую, символьную, строковую) текстовый файл хранит в виде символов, ее изображающих.
Самый привычный нам текстовый файл - это программа на Паскале.
ASCII-код, о котором мы уже говорили раньше, это текстовая кодировка, использующаяся операционной системой DOS.
Управляющие символы не выводятся, а служат для выполнения определенных команд при выводе. Например, если вывести символ с кодом 7, мы услышим короткий звуковой сигнал со спикера.
Компонентный (типизированный) файл содержит любые структурированные данные в машинном представлении, то есть в том же виде, что и в оперативной памяти. Напрямую выводить такие данные на экран или пытаться прочитать их бессмысленно.
Все компоненты типизированного файла имеют один и тот же тип. Тип этот может быть любым, кроме файлового. Например, для многих задач удобно создавать файл записей.
Бестиповый (нетипизированный) файл содержит произвольные наборы байтов. Какой тип имеет каждая последовательность байтов и что она обозначает - остается на совести программиста.
Бестиповые файлы
удобно использовать в задачах, где
данных не так много, чтобы группировать
их в несколько файлов по типам, но
они настолько разноплановые, что
в один компонентный их тоже не объединить.
Кроме этого бестиповые файлы
применяются там, где происходит
работа с содержимым файла без
распознавания информации, например,
когда нужно побайтово
Можно сказать, что нетипизированный файл - это самый низкоуровневый канал ввода-вывода данных в Паскале.
Файл любого типа обязательно содержит специальный код, который указывает на конец файла.
Объявления файловых переменных в Паскале:
type Student = record Family, Name: string; Group: byte; MidMark: real; end; var TextFile: Text; {текстовый файл} ElseTextFile: File of string; {компонентный файл строк - не текстовый!} ComponentFile: File of real; {компонентный файл вещественных чисел} StudentFile: File of Student; {компонентный файл записей} OtherFile: File; {бестиповой файл} |
Общие принципы работы с файлами
2. Основные операции работы с файлами
1) Assign (var FileVar; FileName : string)
Эта директива связывает файловую переменную FileVar с именем физического файла, заданным в строке FileName. Таким образом, все операции, которые мы будем проделывать с переменной FileVar, на самом деле будут изменять физический файл с именем FileName.
Эта связь сохранится до следующего вызова assign с той же переменной FileVar.
После установления связи логический файл считается закрытым и работать с ним еще нельзя.
2) Reset (var FileVar) и Rewrite (var FileVar)
Процедура Reset открывает файл FileVar для чтения. Если открытие прошло успешно, файл считается открытым, и курсор устанавливается на начало его первого элемента. То есть считывать компоненты файла мы всегда начинаем с начала.
Процедура Rewrite открывает файл FileVar для записи. Опять, если все прошло нормально, файл будет готов к записи первого элемента. Обратите внимание, что если файла не существует, он будет создан, а вот если такой файл есть и непустой, все данные в нем автоматически сотрутся, и заполнение начнется с самого начала.
И Reset, и Rewrite мы можем
применить к одному и тому же файлу
многократно. При этом он каждый раз
будет автоматически
3) Close (var FileVar)
Так мы закрываем файл. При этом связь между файловой переменной и физическим файлом не теряется, но текущее состояние файла - "закрыт".
Когда мы записываем данные в файл, они частично могут находиться в буфере оперативной памяти, а на диске сохраняются, когда набирается достаточный их объем. При закрытии файла все данные из памяти дописываются в него. Считается, что Паскаль-машина сама закрывает все файлы данных при выходе из программы. На деле лучше не полагаться на автом атические механизмы и закрывать в программе каждый открытый файл процедурой Close, тогда мы не столкнемся с тем, что последняя порция данных осталась в оперативной памяти и в результате потерялась.
Однако, если мы попытаемся закрыть неоткрытый файл, произойдет сбой программы. Поэтому нужно представлять себе, правильно ли прошла процедура открытия.
Давайте рассмотрим пример. Вот как должен выглядеть код, который открывает и закрывает файл:
program Example; (***************************** * Демонстрация открытия и закрытия файла данных * ****************************** var F: File; {файл данных} bFileIsOpen: boolean; {флаг: файл был открыт} begin Assign (F, 'c:\mywork\mydoc.dat'); {$I-} Reset (F); bFileIsOpen := TRUE; {$I+} if IOResult<>0 then begin {файл открыть не удалось} writeln ('Ошибка: невозможно открыть файл данных.'); bFileIsOpen := FALSE; end; {некие нужные действия} if bFileIsOpen then Close(F); end. |
Если мы попытаемся открыть для чтения несуществующий файл, произойдет сбой программы. Обычно такие ошибки автоматически отслеживаются программой, и если что-то не так, пользователь получает сообщение системы, а программа аварийно завершается. Это не слишком хорошо, поскольку сообщение скорее всего будет на английском, а кроме того программа не должна "выпадать" в систему даже при ошибках.
Поэтому мы отключаем автоматическую проверку ошибок ввода-вывода (директива {$I-}) перед тем, как открыть файл, и включаем ее снова (директива {$I+}) сразу после оператора Reset.
Однако, мы должны знать, открыт ли файл на самом деле, а пользователь должен получить адекватное сообщение об ошибке, если она произошла. Код ошибки ввода-вывода после каждой операции содержится в системной переменной IOResult, и она как обычно равна нулю, если операция закончилась нормально.
Чтобы убедиться, что файл действительно открыт, мы вводим логическую переменную bFileIsOpen, которой присваиваем FALSE, если IOResult не равно нулю, а значит, при открытии F произошла ошибка. Теперь мы закроем файл данных, только если он на самом деле был открыт.
4) Функция EOF (FileVar) : boolean
Эта функция возвращает TRUE, если файловый курсор стоит на маркере конца файла, то есть после последней его записи. При считывании данных из файла практически всегда используется форма:
while not EOF(FileVar) do ... |
То есть работа выполняется, пока не закончится файл.
3. Ввод-вывод данных
Все, что мы можем делать с файлом данных, помимо обслуживающих директив, описанных выше, это чтение информации из файла или запись информации в файл.
Файл - последовательная линейная структура данных. Поэтому и естественный способ обращения к файлу - последовательный. Что касается прямого доступа, то о нем мы еще поговорим ниже.
Ввод-вывод для типизированных файлов
Как мы помним, типизированный файл состоит из однотипных компонентов. Соответственно ввод или вывод осуществляется только через переменную того же типа, что и компоненты файла. Мы можем считать в эту переменную значение следующего компонента или записать значение этой переменной в конец типизированного файла.