Материал: Аверянов Введение в оператсионные системы и основы программирования 2015

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

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

В результате работы этой программы в текущей директории появится файл «info.txt» – обычный текстовый файл. Однако использованные умолчания требуют детальных разъяснений.

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

номер устройства: спецификатор UNIT;

имя файла – спецификатор FILE;

статус файла – спецификатор STATUS;

способ доступа к данным – спецификатор ACCESS;

длина записи – спецификатор RECL;

представление данных – спецификатор FORM;

статус ввода/вывода – спецификатор IOSTAT. Спецификатор UNIT является обязательным, например UNIT=1

врассмотренном примере. При этом достаточно указать только номер, в данном случае это «1». Можно использовать любые номера, кроме «5» и «6», зарезервированных под стандартные устройства или иных зарезервированных, если таковые имеются.

Спецификатор FILE – текстовое выражение, переменная или константа, содержащая имя файла в формате, предусмотренном операционной системой, в рассмотренном примере – это файл в текущей директории: FILE = «INFO.TXT».

Спецификатор STATUS – статус файла с именем, определенным

вспецификации FILE – определяется как скалярная текстовая величина с одним из пяти перечисленных значений:

OLD – открывается уже существующий файл;

NEW – создается новый, еще несуществующий файл;

REPLACE – если файл не существует, то он будет создан, а существующий файл, будет удален и создан новый файл с тем же именем;

196

SCRATCH – создается временный файл, который удаляется после закрытия. Для SCRATCH-файла спецификатор FILE не имеет смысла и не используется;

UNKNOWN – для существующего файла устанавливает статус OLD, а для несуществующего – статус NEW. UNKNOWN назначается по умолчанию, если спецификатор STATUS явно не прописан в операторе OPEN (см. пример 3.89).

Когда статус файла явно не задан, то при компиляции программы иногда выдается соответствующее предупреждение (warning), которое начинающие программисты часто принимают за ошибку.

Спецификатор ACCESS – способ доступа к данным, определяется скалярным текстовым выражением, принимающим одно из двух значений: SEQUENTIAL (файл последовательного доступа) или DIRECT (файл прямого доступа). Файлы прямого доступа состоят из записей одинаковой длины, и к произвольной записи файла можно обратиться по ее номеру. Файлы последовательного доступа могут состоять из записей произвольной длины, а от текущей записи можно перейти только к следующей или предыдущей. Если способ доступа к данным явно не указан (см. пример 3.89), то считается что это файл – последовательного доступа.

Спецификатор RECL – длина одной записи файла (в байтах или машинных словах), актуальна только для файлов прямого доступа.

Спецификатор FORM задается скалярным текстовым выражением и определяет форму представления данных: FORMATTED, соответствующее форматному представлению данных или UNFORMATTED, соответствующее бесформатному представлению данных. Если форма представления не указана, то файл последовательного доступа считается форматным (см. пример 3.89), а файл прямого доступа – бесформатным. Форматный (по сути, текстовый) файл содержит данные в удобочитаемом для человека виде. Эти данные могут считываться и записываться с использованием спецификаций формата. Бесформатный файл не предполагает визуального прочтения и хранит данные во внутреннем машинном представлении.

Спецификатор IOSTAT характеризует состояние ввода/вывода и задается как любая целая скалярная переменная, например IOSTAT= IOS, при этом IOS = 0 означает успешную операцию ввода/вывода, а любое другое значение констатирует ошибку.

197

Для предъявления оператора OPEN в развернутом виде целесообразно разделить пример 3.89 на две части (примеры 3.90 и 3.91).

Пример 3.90. Оператор OPEN в развернутом виде program FINOUT2

real :: X=1., Y=2., Z=3.

open(unit=1, file= "info.txt", status="new", access= "sequential", & form="formatted", iostat =IOS)

if (IOS /=0) then

print*, "Ошибочка вышла! "

stop !Оператор останова программы end if

write(1,*) X, Y, Z close(1)

end

Если при запуске программы (см. пример 3.90) в текущей директории присутствует файл INFO.txt с явно указанным для него статусом NEW в операторе OPEN, то программа завершится по ошибке: «IOS > 0». Файл INFO.txt является результатом работы программы и должен появиться после ее запуска.

Пример 3.91. Открытие, запись, чтение и закрытиефайлов program FINOUT3

open(unit=4, file= "info.txt", status= old , access= "sequential", & form="formatted", iostat =IOS)

if (IOS /=0) then

print*, "Ошибочка вышла! "

stop !Оператор останова программы end if

read(4,*) X, Y, Z close(4)

print *, X, Y, Z end

Для корректной работы программы (см. пример 3.91) требуется наличие в текущей директории файла INFO.txt – результата работы предыдущего примера. Если такого файла не окажется, то программа завершится с ошибкой: «IOS > 0», поскольку для файла данных INFO.txt явно указан статус OLD в операторе OPEN.

В операторах READ и WRITE при работе с текстовыми файлами могут использоваться все дескрипторы формата ввода/вывода дан-

198

ных (см. п. 3.6.3). Однако помимо номера устройства и спецификации формата, операторы READ и WRITE могут содержать и другие спецификаторы, например спецификатор IOSTAT в точности такой же, как для оператора OPEN.

Наличие спецификатора IOSTAT в операторах READ и WRITE позволяет программисту самостоятельно обрабатывать ошибки чтения и записи в штатном режиме, без прерывания работы программы. Это может быть весьма актуально при обработке текстовых файлов с заранее неизвестным количеством текстовых строк, например при копировании одного файла в другой (пример 3.92).

Для работы этого примера в текстовом редакторе потребуется подготовить небольшой текстовый файл с именем FILE1.txt, в котором не менее трех строк, каждая не длиннее 80-ти символов. На выходепрограмма создаст копию файла FILE1.txt в файлес именем

FILE2.txt.

Пример 3.92. Копирование файлов program FINOUT4

character (LEN =80) STRING open(unit=1, file= "file1.txt") open(unit=2, file= "file2.txt") do

read (1, ‘(A80)’, iostat = IOS) STRING write (2, ‘(A80)’) STRING

if (IOS >0) exit ! Цикл завершен по достижении конца файла end do

close(1); close(2) end

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

При помощи оператора BACKSPACE можно из любой позиции файла перейти к предыдущей (или только что прочитанной) записи файла, а при помощи оператора REWIND – перейти к началу файла. В качестве параметра оба оператора используют номер ассо-

199

циированного с файлом устройства, например BACKSPACE 1 или REWIND 4. Если файл уже позиционирован в начало, то применение этих операторов не повлечет за собой ошибки или изменения в позиционировании. Проиллюстрировать возможности позиционирования можно на своеобразном «плеере» файла с элементами «перемотки» записей (пример 3.93). Для работы программы потребуется текстовый файл с именем FILE1.txt, с несколькими строками, не длиннее 80-ти символов.

Пример 3.93. «Перемотка записей» текстовогофайла program FINOUT5

integer(kind=1):: ACTION, IOS=0 character (LEN =80) STRING open(unit=1, file= "file1.txt")

do

read (1, '(A80)' , iostat = IOS) STRING

if (IOS /=0) exit

! Цикл завершен по достижении конца файла

print '(A80)', STRING

! Печать строки, считанной из файла

print '("1 - читать дальше, 2 - шаг назад, 3 - в начало, ", i1 $)' read *, ACTION

if (ACTION ==1) cycle if (ACTION ==2) then

backspace 1; backspace 1

! backspace 2 раза, иначе backspace + read из файла = стояние на месте endif

if (ACTION ==3)rewind 1 end do

print *, "Достигнут конец файла" close(1)

end

В заключение стоит отметить, что в любой позиции файла, используя оператор ENDFILE, можно внести запись «Конец файла», при этом все последующие строки файла будут утеряны. В качестве параметра оператору ENDFILE указывается номер устройства,

так же как для BACKSPACE и REWIND.

Описание программирования ввода/вывода для файлов прямого доступа (ACCESS = «DIRECT») и бесформатной формой представления данных (FORM = «UNFORMATTED») выходит за рамки данного учебного пособия.

200

Источник: https://studfile.net/preview/16708824/