Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Иванова Г.С. - Основы программирования

.pdf
Скачиваний:
2770
Добавлен:
02.04.2015
Размер:
13.53 Mб
Скачать

6. Файловая система. Файлы

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

Логические устройства используют для организации обмена информа­ цией с основными устройствами ввода-вывода, такими как дисплей, клавиа­ тура и т. п. Логические устройства имеют стандартные имена, например:

CON - консоль: при выводе данных соответствует экрану, при вводе - клавиатуре;

Р1Ш - принтер;

NUL - «пустое устройство», обычно заменяет устройство вывода отла­ дочной информации после завершения отладки программы.

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

Доступ к компоненту файла осуществляется через указатель файла. При выполнении операции чтения или записи указатель автоматически пере­ мещается на следующий компонент (рис. 6.2).

Для идентификации файлов в Borland Pascal используют фашовые пере­ менные, В зависимости от способа представления информации различают три типа файлов, соответственно различаются и способы описания файло­ вых переменных (рис. 6.3).

Типизированные файлы. Файловая переменная типизированного файла описывается как

Туре <идентификатор файловой переменной> =

Jile о/<тип компонента>;...

где <тип компонента> - любой тип данных, кроме файлового.

Указатель файла

Маркер конца [тйла

Рис. 6.2. Организация файла

191

Часть I. Основы алгоритмизации и процедурное программирование

r&i

~р*/^Г|1еЛ-

Тип

компонента

text

Рис. 6.3. Синтаксическая диаграмма <Файловый тип>

Типизированные файлы используют, когда обрабатывают хранящуюся в файле или передаваемую с устройства/на устройство последовательность компонентов одинаковой длины (чисел, записей и т.п.).

Текстовые файлм - тип файловой переменной описывается так:

Туре <идентификатор файловой переменной> = text;...

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

Нетипшироваииые файлы:

Туре <идентификатор файловой переменной> =/ile;...

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

Как и любая переменная языка Borland Pascal, файловая переменная мо­ жет быть описана в инструкции объявления переменных, например:

Var

F1: file of real;

 

F2:file:

 

F3: text;...

или с предварительным объявлением типа:

Туре FF =file of integer; VarFLFF;.,.

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

Туре FF ^file of integer;

Procedure Print (Var F1:FF);...

192

6. Файловая система, Фащы

Работа с файлом включает:

инициализацию файловой переменной - установление связи файлово

переменной с файлом;

открытие файла - подготовку файла для выполнения операций вво­ да/вывода;

обработку компонентов фашавыполнение операций ввода-вывода;

закрытие файла (при повторном открытии файл закрывается автома­ тически).

Инициализация файловой переменной. Связь между физическим ус­ тройством (дисководом или внешним устройством) и файловой переменной устанавливается специальной процедурой.

Процедура Assign (Var f; sUstring) - инициализирует файловую пере­ менную f, связывая ее с файлом или логическим устройством, определенным строкой St.

Если файл находится в текущем каталоге, то достаточно указать имя файла и его расширение. В противном случае необходимо указать полное имя файла, например:

Туре FI1 = text;

Var flfifi: FIl;

Assign (fl, Tl.dat'); {связывание файловой переменной с файлом в текущем каталоге}

Assign (f2, 'd:\iva\a.dat'): {связывание файловой переменной с файлом в указанном каталоге}

Assign(f3, VON'); {связывание файловой переменной с консолью}

Открытие файла. Открытие файла предполагает указание направления передачи данных. В Borland Pascal файл можно открыть для чтения и для за­ писи. Текстовый файл можно открыть также для добавления строк. В типи­ зированный файл, открытый для чтения, можно дописывать новые записи или писать в нем новые записи на место старых.

1. Процедура ReSet(VarJ) - открывает файл, определенный файловой переменной f для чтения. При выполнении этой процедуры указатель файла устанавливается на первый компонент файла (физически первый блок запи­ сей считывается в буфер). Логическое устройство в этом случае готовится к выполнению операций ввода.

При открытии для чтения несуществующего файла регистрируется ошибка выполнения, а функция lOResult типа Word возвращает значение, от­ личное от О (см. далее описание функции). Отключив контроль операций ввода-вывода и используя функцию lOResult, можно организовать проверку наличия файла с указанным именем на диске:

193

Часть 1. Основы алгоритмизации и процедурное программирование

Var f: file of char;

Begin

Assign(f, *a. dat * ) ; {инициализация файловой переменной} {$ I'} {отмена контроля ошибок ввода-вывода}

ReSet (f); {открытие файла для чтения} {$ /+/ {включение контроля ошибок}

iflOResult оО then

WriteLn ('Файл не существует *);

else

WriteLn('0awi существует *);...

2.Процедура ReWrite(VarJ) - открывает файл, определенный файловой переменной f, для записи. При открытии для записи существующего файла старый файл уничтоэюается без предварительной проверки и выдачи предупреэюдения пользователю. Если файла с таким именем не существовало, то он создается и подготавливается к записи (физически ~ очищается буфер). Логическое устройство при этом подготавливается к приему информации.

3.Процедура AppEnd(Var fiiext) - открывает текстовый файл, опреде­ ленный файловой переменной f, для добавления строк.

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

Любой программе без объявления, инициализации файловой перемен­ ной и открытия доступны два файла со стандартными файловыми перемен­ ными:

INPUT - чтение со стандартного устройства ввода;

OUTPUT - вывод на стандартное устройство вывода.

Это текстовые файлы, используемые для выполнения элементарных операций ввода-вывода. В операторах ввода-вывода файловые переменные этих файлов обычно не указывают (см. параграф 2.6). Остальные файлы ста­ новятся доступными только после связывания файловой переменной с фай­ лом или логическим устройством и открытия файла.

Стандартным устройством ввода MS DOS по умолчанию является кла­ виатура. Стандартным устройством вывода - экран дисплея.

Примечание. При необходимости эти устройства можно переназначить средствами опе­ рационной системы. Так, для организации ввода данных из файла вместо ввода с клавиатуры необходимо запустить программу из командной строки MS DOS, указав после имени програм­ мы символ «<» и имя файла, а для организации вывода в файл вместо вывода на экран - сим­ вол «>» и имя файла. Можно перенаправить только ввод или только вывод или и то и другое сразу.

Например:

A:\>example.exe <a.dat >a.res - ввод из файла a.dat, а вывод в файл a.rez.

194

б. Файловая система. Файлы

Такое переназначение будет выполнено, если в программе не используется модуль crt (см. парафаф 8.1), который организует операции ввода-вывода напрямую, непосредственно взаимодействуя с устройством.

Обработка компонентов файла. Основные операции над компонента­ ми - это операции записи и чтения. На базе этих операций выполняют более сложные операции:

создание файла - занесение в файл требуемых записей;

модификация файла - изменение всех или нескольких записей, добав­ ление и удаление записей;

поиск нужной информации в файле.

Выполнение этих операций осуществляется по-своему для каждого ти­ па файла (см. параграфы 6.3 - 6.5).

Закрытие файла. Закрытие файла, открытого для записи или чтения, осуществляется процедурой

Close(VarJ).

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

Стандартные процедуры и функции обслуживания файлов. Для вза­ имодействия с файловой системой MS DOS в Borland Pascal определены стандартные процедуры и функции, которые применимы к файлам любых типов.

1. Процедура ReName(Varf; name:string) - осуществляет переименова­ ние файла, определенного файловой переменной f. Новое имя файла задает­ ся параметром name. Если в процессе работы программы требуется переиме­ новать файл, открытый для чтения или записи, необходимо предварительно закрыть этот файл. При совпадении нового имени файла с каким-либо уже существующим выдается сообщение об ошибке.

2.Процедура Erase(Var J) - осуществляет удаление созданного или на­ ходящегося в процессе формирования файла. Перед уничтожением файл должен быть закрыт, так как разрешается удалять только закрытые файлы.

3.Функция EOF(Var J):boolean - определяет конец файла. Как было от­ мечено выше, размер файла при его создании не фиксируется. Поэтому в процессе работы требуется проверка достижения конца файла. Функция при­ нимает значение TRUE, если указатель стоит в конце файла (после послед­ ней записи). При этом, если производится чтение, то это означает, что файл исчерпан, а если идет запись, то новая запись дописывается в конец файла. Функция принимает значение FALSE, если конец файла еще не достигнут.

195

Часть 1. Основы алгоритмизации и процедурное программирование

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

В качестве маркера конца файла используется символ ASCII с кодом 26 (#26). При рабо­ те с клавиатурой этот код формируется при вводе комбинации CTRL-Z. Считается, что при­ знак конца файла физически присутствует в файле, однако, как правило, такой символ в кон­ це дискового файла отсутствует, и конец файла в системе определяется другим способом.

4.Функция IOResult(Var J): word - возвращает код правильности вы­ полнения операций ввода/вывода. Если ошибок не зафиксировано, то функ­ ция возвращает 0. Информация об ошибках может быть получена и обрабо­ тана в режиме компилятора {$!-}- отключение контроля ошибок ввода/вы­ вода.

5.Процедура Truncate(Var/) - обрезает файл, оставляя компоненты до того, на который ссылается указатель файла (кроме текстовых файлов).

6.Процедура ChDir(path:string) - изменяет текущий каталог: назначает текущим каталог, указанный параметром path.

7.Процедура GetDir(drive:word: Var dir:string) - возвращает имя теку­ щего каталога на указанном устройстве, где устройство drive: О - устройст­ во по умолчанию; 1 - диск А; 2 - диск В и т.д.

8.Процедура MkDir(dir:string) - создает новый каталог. Строка dir оп­ ределяет путь и новое имя.

9.Процедура RmDir (dinstring) - удаляет каталог с указанным именем. Каталог должен быть пустым.

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

Текстовый файл - это файл, компонентами которого являются символь­ ные строки переменной длины, заканчивающиеся специальным маркером конца строки (рис. 6.4).

Указатель файла

 

 

Маркер конца файла

Строка 1 PI Строка 2 | |

Строка 3

[

Компонент 4

 

Маркер конца строки

 

Рис. 6.4. Структура текстового файла

196

6. Файловая система. Файлы

Примечание, Маркер конца строки - это последовательность из двух специальных сим­ волов по таблице ASCII «#13, #10». Символ с кодом 13 интерпретируется в компьютере как команда установки курсора в начало строки, а символ с кодом 10 - как команда перехода на следующую строку. Как уже упоминалось ранее, такая комбинация кодов вводится при нажа­ тии клавиши ENTER.

Текстовый файл можно открыть для записи, чтения и добавления запи­ сей в конец (см. параграф 6.2). Файл, открытый для записи, не может исполь­ зоваться для чтения и наоборот. При открытии файла для добавления систе­ ма проверяет, не был ли файл открыт для чтения или записи, и если такое от­ крытие имело место, то производится сначала закрытие файла, а затем уже открытие для добавления.

Текстовые файлы используют для хранения и обработки текстовой ин­ формации: символов, строк, символьных массивов. Логические и числовые данные при записи в текстовые файлы должны преобразовываться в сим­ вольные строки.

Следует иметь в виду, что при необходимости текстовый файл может быть создан или прочитан любым текстовым редактором, в том числе и тек­ стовым редактором, входящим в состав среды Borland Pascal.

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

ифункции.

1.Функция EOLn( [Var J]): boolean - возвращает TRUE, если во вход­ ном текстовом файле достигнут маркер конца строки; при отсутствии файло­ вой переменной проверяется стандартный файл INPUT, который обычно свя­ зан с клавиатурой.

Примечание, Функция EOLn, как и EOF, по-разному работает с дисковыми файлами и логическими устройствами. Для логического устройства невозможно предвидеть, каким будет результат чтения очередного символа. Поэтому при работе с логическим устройством функ­ ция EOLN возвращает TRUE, если последним считанным символом был символ #13. При ра­ боте с диском функция EOLN возвращает TRUE, если следующим считанным символом бу­ дет символ #13.

2. Процедура Read( [Var f:text;] vl, v2,... vn) - обеспечивает ввод сим­ волов, строк и чисел. Список ввода представляет собой последовательность из одной или более переменных типа CHAR, STRFNG, а также любого цело­ го и вещественного типа. При отсутствии файловой переменной ввод осуще­ ствляется из стандартного файла INPUT.

При вводе значений переменных типа CHAR выполняется чтение одно­ го символа из файла, считанное значение присваивается очередной перемен­ ной из списка ввода. Как уже упоминалось в параграфе 2.6, символы вводят­ ся подряд, а не через пробел, как числа. Если перед выполнением чтения ука­ затель файла достиг конца очередной строки, то результатом чтения будет символ #13, а если был достигнут конец файла, то - символ #26.

197

Часть L Основы алгоритмизации и процедурное программирование

При вводе переменных типа STRING количество считанных процедурой и помещенных в строку символов равно максимальной длине строки, если раньше не встретились маркеры конца строки или конца файла, которые в строку не включаются. Символы, выходящие за размер максимальной длины строки, отбрасываются. Новое обращение к процедуре Read вернет пустую строку (см. также параграф 2.6). Следовательно, процедура Read не в состо­ янии читать последовательность строк, так как первая строка будет прочита­ на правильно, а все последующие окажутся пустыми.

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

Ввод логических констант процедурами Read и ReadLn не предусмот­

рен.

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

3. Процедура ReadLn( [Var f;] vl,v2, ,..,vn ) - также обеспечивает ввод символов, строк и чисел. Процедура использует те же правила ввода, что и процедура Read, но после чтения последней переменной оставшаяся часть строки до маркера конца строки пропускается, так что следующее обраще­ ние к ReadLn или Read начнется с первого символа новой строки. Процеду­ ра может быть вызвана без указания списка ввода, что приведет к пропуску всех символов текущей строки до маркера конца строки.

Процедуры Read и ReadLn могут использоваться без указания файловой переменной. Тогда операция чтения осуществляется из стандартного файла INPUT. Использование процедуры ReadLn без параметров после процедуры Read приведет к очистке буфера ввода. Применение этой же процедуры без предшествующей ей процедуры Read переводит программу в состояние вво­ да, т.е. выполнение программы приостанавливается до нажатия клавиши ENTER, что может использоваться для организации паузы на время просмо­ тра содержимого экрана.

4. Процедура Write( [Var /•] v7,v2, ...,vn ) - обеспечивает вывод данных в текстовый файл или передачу их на логическое устройство. Список выво­ да - последовательность из одного или более выражений типа CHAR, STRING, BOOLEAN, а также целого или вещественного типов. При выводе числовых значений последние преобразуются в символьное представление. При отсутствии файловой переменной вывод осуществляется в стандартный файл OUTPUT, который обычно назначен на экран.

198

6. Файловая система. Файлы

Любой параметр из списка вывода может иметь формат:

<параметр> [: <целое1> [: < целое2> ]],

где <целое1> и <целое2> интерпретируются в соответствии с правилами, описанными в параграфе 2.6.

5.Процедура WriteLn( [Var /;] vl,v2, ...,vn ) ~ обеспечивает вывод ин­ формации в текстовый файл или ее передачу на логическое устройство выво­ да. При отсутствии файловой переменной вывод осуществляется в стандарт­ ный файл OUTPUT, который обычно связан с дисплеем.

Процедура полностью идентична процедуре Write, за исключением то­ го, что выводимая строка символов завершается символами #13 и #10. При вызове WriteLn допускается опускать список вывода, в этом случае в файл передается маркер конца строки (при выводе на экран это приведет к перево­ ду курсора в начало следующей строки).

6.Функция SeekEOLn( [Var /] ):boolean - пропускает все пробелы и знаки табуляции до маркера конца строки или до первого значащего симво­ ла и возвращает TRUE при обнаружении маркера. Если файловая перемен­ ная не указана, то функция проверяет стандартный файл INPUT.

7. Функция SeekEOF( [Var /]):boolean - пропускает все пробелы, зна­ ки табуляции и маркеры конца строки до маркера конца файла или до перво­ го значащего символа и возвращает TRUE при обнаружении маркера. Если файловая переменная отсутствует, то функция проверяет стандартный файл INPUT

Рассмотрим несколько примеров.

Пример 6.1. Разработать программу, которая формирует текстовый файл из 26 строк, содержащих случайное количество соответствующих про­ писных букв латинского алфавита, например:

ААААА

ВВВВВ

С

DDDDDDDDDDDDDDDDDDDDD

ЕЕЕЕЕЕЕЕЕЕЕЕЕЕ и т.д.

Program formjextjile; Var

fitext; {файловая переменная для текстового файла}

а:char; n,i:integer; fname,st:string[30]; Begin

WriteLnCВведите имя файла'); ReadLn(fiiame); Assign(f/name); {инициализируем файловую переменную} ReWrite(f); {открываем файл для записи}

Randomize; {инициализируем датчик случайных чисел}

199

Часть 1. Основы алгоритмизации и процедурное программирование

for а:='А'

to 'Z' do

{формируем строки}

begin

 

 

n:=Random(30)+l:

for

i:=l to n do

st:=st+a:

WriteLn(fySt);

{записываем строку в текстовый файл}

WriteLn{st);

{для контроля - выводим ее на экран}

end;

 

 

Close(f);

{закрываем файл}

End,

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

Пример 6.2. Разработать программу, которая удаляет из текстового фай­ ла «пустые» строки: строки, не содержащие символов, и строки, содержащие только пробелы и знаки табуляции.

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

непустые строки файла.

 

 

Program ex;

 

 

 

 

VarflJ2:text;

{файловые переменные текстовых файлов}

st.name:string;

 

 

Begin

 

 

 

 

WriteLnCВведите имя файла:'); ReadLn(name);

Assign(fl,name);

{инициализируем файловую переменную}

{$!'}

{проверяем существование файла}

Reset(fl);

 

 

 

{$Щ

 

 

 

 

ifIOResult=0

then

 

{если файл с заданным именем существует}

begin

 

 

 

 

Assign(f2/temp.dat');

{инициализируем новый файл}

Rewrite(f2);

 

 

{открываем новый файл для записи}

while not EOF(fl)

do {пока не достигнут конец файла}

begin

 

 

 

 

if SeekEOLn(fl)

then ReadLn(flySt) {если строка пустая,

 

 

 

 

то пропускаем ее}

200