современный фортран , Бортеньев. О. В. Бартеньев Современный Фортран
Скачать 2.24 Mb.
|
354 11. Операции над внешними файлами delim - скалярное символьное выражение, задающее ограничитель для символьных данных при В/В под управлением именованного или неименованного списка. Выражение может вычисляться со значениями 'APOSTROPHE', 'QUOTE' или 'NONE' (по умолчанию). Если ограничитель задан, то внутренние, совпадающие с ограничителем символы строки (апостроф (') или кавычки (")) удваиваются (разд. 9.9.1.2). dis - скалярное символьное выражение, задающее статус файла после его отсоединения от устройства. Принимает одно из следующих значений: • 'KEEP' или 'SAVE' - файл сохраняется; • 'DELETE' - файл удаляется; • 'PRINT' - файл подается на печать и сохраняется (только для последовательных файлов); • 'PRINT/DELETE' - файл подается на печать и удаляется (только для последовательных файлов); • 'SUBMIT' - расщепляет процесс для исполнения файла; • 'SUBMIT/DELETE' - расщепляет процесс для исполнения файла и удаляет его после завершения операций. По умолчанию действует статус 'DELETE' для scratch-файлов и 'KEEP' - для всех остальных. Вторая форма спецификатора - DISP = dis. err - метка исполняемого оператора. При возникновении ошибки управление передается на оператор, имеющий метку err. file - символьное выражение, задающее имя файла, подсоединяемого к устройству с номером u. Если спецификатор FILE не задан, то создается временный, стираемый после выполнения оператора CLOSE или после нормального завершения программы файл. При этом должен быть задан спецификатор STATUS со значением SCRATCH, например: open(1, status = 'scratch', form = 'bynary') Если параметр file вычисляется со значением пробел, то выполняются следующие действия: • программа читает имя файла из списка аргументов (если таковые имеются) в командной строке, запускающей программу. Если аргументом является нулевая строка (''), то имя файла будет предложено ввести пользователю. Каждый последующий оператор OPEN, имеющий в качестве имени файла пробел, читает соответствующий аргумент командной строки; • если операторов OPEN, имеющих в качестве имени файла пробел, больше, чем аргументов командной строки, программа потребует ввести недостающие имена файлов. Если имя файла 'USER' или 'CON', то вывод выполняется на экран, ввод - с клавиатуры. Имя file может задавать и другие физические устройства, например принтер (FILE = 'PRN') или первый последовательный порт 355 О. В. Бартеньев. Современный ФОРТРАН (FILE = = 'COM1'). В приложениях QuickWin задание FILE = 'USER' позволяет открыть дочернее окно. Тогда все операции В/В, связанные с устройством, к которому это окно подсоединено, выполняются на это окно. form - символьное выражение, вычисляемое со значениями 'FORMAT- TED', 'UNFORMATTED' или 'BINARY'. Если доступ к файлу последовательный, то по умолчанию устанавливается форма 'FORMATTED'. Если доступ прямой, то по умолчанию устанавливается форма 'UNFORMATTED'. iofocus - логическое выражение, в случае истинности которого дочернее окно приложения QuickWin устанавливается в фокусе (располагается поверх других окон) при выполнении операторов READ, WRITE и PRINT. Является расширением над стандартом Фортран 90. iostat - целочисленная переменная, возвращающая 0 при отсутствии ошибок, отрицательное число, если возникла ситуация "конец файла", или номер возникшей ошибки. mr - скалярное выражение, задающее максимальное число записей, которое может быть передано при работе с прямым файлом в период его подсоединения к устройству. При необходимости преобразовывается в целый тип. По умолчанию число передаваемых записей не ограничено. mode - символьное выражение, задающее подобно action возможные действия с файлом и вычисляемое со значениями 'READ' (процесс может только читать данные из файла), 'WRITE' (возможен только вывод данных в файл) или 'READWRITE' (возможен как ввод, так и вывод данных). Является расширением над стандартом Фортрана. org - скалярное символьное выражение, задающее внутреннюю организацию файла, вычисляемое со значением 'SEQUENTIAL', если задается файл с последовательной организацией (действует по умолчанию), или 'RELATIVE', если задается файл со связанной организацией. pad - символьное выражение, вычисляемое со значениями 'YES' (по умолчанию) или 'NO'. В случае 'YES' если при форматном вводе требуется больше данных, чем содержится в записи, то недостающее число данных восполняется пробелами. Если же PAD = 'NO', то при попытке форматного ввода большего числа данных, чем содержится в записи, возникнет ошибка ввода. Например: character(20) :: st open(1, file = 'a.txt', pad = 'yes') read(1, '(a)') st ! Читаем из файла и выводим на экран print *, st ! abcd read * ! Ждем нажатия Enter ! Изменяем свойство подсоединения PAD файла a.txt open(1, file = 'a.txt', pad = 'no') ! По умолчанию POSITION = 'ASIS' read(1, '(a)') st ! Возникнет ошибка ввода Файл a.txt: 356 11. Операции над внешними файлами abcd efgh position - символьное выражение, задающее способ позиционирования файла при последовательном доступе и которое должно вычисляться со значениями 'ASIS', 'REWIND' или 'APPEND'. Если имеет место 'REWIND', то существующий файл позиционируется в начало файла. В случае 'APPEND' существующий файл позиционируется непосредственно перед записью "конец файла". В случае 'ASIS' (задается по умолчанию) позиция ранее подсоединенного файла не изменяется, в то время как ранее неподсоединенный файл позиционируется в свое начало. READONLY – так же как и при задании ACTION = 'READ', файл подсоединяется только для чтения. Однако READONLY предотвращает удаление файла, если присутствует спецификатор STATUS = 'DELETE'. recl - целочисленное выражение, задающее длину каждой записи в байтах. Этот параметр задается только в файлах прямого доступа. rtyp - скалярное символьное выражение, задающее тип записей файла и вычисляемое с одним из следующих значений (см. также разд. 10.5): • 'FIXED' - записи фиксированной длины; • 'VARIABLE' - записи переменной длины; • 'SEGMENTED' - сегментированные записи; • 'STREAM' - поток; • 'STREAM_LF' - LF_поток; • 'STREAM_CR' - CR_поток. При подсоединении файла действуют умолчания: • 'FIXED' - для связанных файлов и файлов с последовательной организацией, открытых для прямого доступа; • 'STREAM_LF' - для форматных файлов с последовательной организацией; • 'VARIABLE' - для неформатных файлов с последовательной организацией. share - символьное выражение, вычисляемое со значениями 'DENYRW', 'DENYWR', 'DENYRD' или 'DENYNONE': • 'DENYRW' - (deny-read/write mode) пока файл открыт в этом режиме, никакой другой процесс не может открыть этот файл ни для чтения, ни для записи; • 'DENYWR' - (deny-write mode) пока файл открыт в этом режиме, никакой другой процесс не может открыть этот файл для записи; • 'DENYRD' - (deny-read mode) пока файл открыт в этом режиме, никакой другой процесс не может открыть этот файл для чтения; • 'DENYNONE' - (deny-none mode) пока файл открыт в этом режиме, любой другой процесс может открыть этот файл как для чтения, так и для записи. 357 О. В. Бартеньев. Современный ФОРТРАН SHARED - подсоединяемый файл открывается для разделенного доступа, при котором к файлу могут обращаться более одного приложения. status - символьное выражение, которое может принимать значения 'OLD', 'NEW', 'SCRATCH', 'REPLACE' или 'UNKNOWN': • 'OLD' - файл должен уже существовать, в противном случае возникнет ошибка В/В; • 'NEW' - файл не должен существовать. Если он не существует, то он будет создан, в противном случае возникнет ошибка В/В; • 'SCRATCH' - если в операторе OPEN опущен параметр file, то по умолчанию значение status равно 'SCRATCH'. Создаваемые 'SCRATCH'- файлы являются временными и уничтожаются либо при закрытии устройства, либо при завершении программы; • 'REPLACE' - открываемый файл замещает существующий файл с тем же именем. Если такого файла не существует, то создается новый файл; • 'UNKNOWN' (по умолчанию) - процесс прежде пытается открыть файл со статусом 'OLD', затем - со статусом 'NEW'. Если файл существует, то он открывается, если нет - создается. Значение status затрагивает только дисковые файлы и игнорируется при работе с устройствами. Пример: character(70) fn write(*, '(a\)') 'Введите имя файла: ' read(*, '(a)') fn ! Открываем неформатный новый файл прямого доступа ! Файл fn должен отсутствовать на диске open(7, file = fn, access = 'direct', status = 'new') Подсоединение файла к устройству звездочка (*) не имеет никакого действия, поскольку это устройство постоянно связанно с клавиатурой и экраном. Однако можно подсоединить внешний файл к существующим по умолчанию устройствам 0, 5 и 6. Если в операторе OPEN использовано устройство, подсоединенное ранее к другому файлу, то ранее открытый файл автоматически закрывается, а затем другой файл открывается и подсоединяется к заданному параметром u устройству. Нельзя одновременно подсоединить один и тот же файл к разным устройствам. Если файл не открыт и выполняется оператор READ или WRITE, то программа попытается открыть файл так, как это делает оператор OPEN, в котором задан параметр FILE = ' '. Если оператор OPEN подсоединяет устройство к несуществующему файлу, то файл открывается со свойствами, заданными в операторе. Можно использовать оператор OPEN, указывая в нем имя уже подсоединенного файла с тем же устройством для изменения свойств 358 11. Операции над внешними файлами подсоединения, задаваемых спецификаторами BLANK, DELIM, PAD, ERR и IOSTAT. В таких случаях спецификатор POSITION = 'APPEND' игнорируется, но спецификатор POSITION = 'REWIND' вызывает перемещение на начало файла. Пример: integer(4) :: k open(7, file = 'a.txt', blank= 'zero') write(7, '(2i3)') 1, 2 rewind 7 read(7, '(i6)') k ! Возвращает 1002 ! Изменяем свойство подсоединения BLANK файла a.txt open(7, file = 'a.txt', blank = 'null') rewind 7 read(7, '(i6)') k ! Возвращает 12 end title - символьное выражение, задающее имя дочернего окна QuickWin. Если спецификатор TITLE задан в приложении, которое не является Quick- Win, то возникнет ошибка выполнения. USEROPEN = function name - спецификатор, позволяющий передать управление внешней функции function name, непосредственно открывающей файл. Вызываемая функция должна иметь атрибут EXTER- NAL, открывать файл, используя функцию CreateFile, и возвращать дескриптор файла, вырабатываемый CreateFile; используется, когда нужно задать не предусмотренные оператором OPEN свойства подсоединения. Основное назначение спецификатора - использовать возможности WIN32 API функции CreateFile, находящейся, кстати, в библиотеке kernel32.lib. Пример. Приводимый код можно употребить для вызова заданной спецификатором USEROPEN функции. При выполнении оператора OPEN передается управление функции fileopen, которая вызывает функцию Cre- ateFile. Необходимые для работы CreateFile данные собраны в модуле MTY, интерфейс CreateFile размещен в fileopen. character(30) :: st, fn integer(4), external :: fileopen fn = 'a.dat'c ! СИ-строка, завершаемая null-символом open(1, file = 'a.dat', status = 'old', useropen = fileopen, err = 10) write(1, *) 'Test string' rewind 1 ! Переход на начало файла read(1, '(a)') st print *, st ! Test string stop 'OK' ! Файл удачно открыт 10 print *, 'Error' end 359 О. В. Бартеньев. Современный ФОРТРАН module mty ! Вместо модуля DFWINTY ! Константа file_flag_write_through взята из файла dfwinty.f90 integer, parameter :: file_flag_write_through = #80000000 type t_security_attributes ! Взят из файла dfwinty.f90 sequence integer(4) :: nLength, lpSecurityDescriptor logical(4) :: bInheritHandle end type t_security_attributes end module mty ! Возможный вид функции fileopen integer function fileopen(lpFileName, dwDesiredAccess, dwShareMode, & lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, & hTemplateFile, unit) !dec$attributes reference :: dwDesiredAccess !dec$attributes reference :: dwShareMode !dec$attributes reference :: dwCreationDisposition !dec$attributes reference :: dwFlagsAndAttributes !dec$attributes reference :: unit use mty ! Вместо USE DFWINTY ! Интерфейс CreateFile взят из kernel32.f90. Однако в оригинале lpFileName ! имеет тип CHARACTER*(*), что неверно. Ниже ошибка исправлена interface integer(4) function CreateFile(lpFileName, dwDesiredAccess, dwShareMode, & lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, & hTemplateFile) !dec$ attributes default :: CreateFile !dec$ attributes stdcall, alias : '_CreateFileA@28' :: CreateFile !dec$ attributes reference :: lpFileName !dec$ attributes reference :: lpSecurityAttributes use mty ! Вместо USE DFWINTY integer(4) :: lpFileName ! Правильное объявление типа integer :: dwDesiredAccess, dwShareMode type(t_security_attributes) lpSecurityAttributes integer :: dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile end function CreateFile end interface integer(4) :: lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, & dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile, unit type(t_security_attributes), pointer :: null_sec_attr ! Битовый флаг записи file_flag_write_through для CreateFile dwFlagsAndAttributes = dwFlagsAndAttributes + file_flag_write_through ! Открывает файл с помощью CreateFile fileopen = CreateFile(lpFileName, dwDesiredAccess, dwShareMode, & null_sec_attr, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile) end function fileopen 360 11. Операции над внешними файлами Первые 7 параметров функции передаются из CVF и соответствуют списку параметров CreateFile. Их значения берутся из соответствующего оператора OPEN: lpFileName - адрес СИ-строки, содержащей имя файла; dwDesiredAccess - желаемый доступ; dwShareMode - вид доступа (монопольный или разделяемый); lpSecurityAttributes - в Фортране всегда null; передается для ссылки на структуру security_attributes; dwCreationDisposition - вид выполняемых с файлом действий; dwFlagsAndAttributes - атрибуты файла и его флаги; hTemplateFile - всегда null; передается для дескриптора временного файла функции CreateFile. Последний параметр - устройство, указанное в операторе OPEN. 11.5. Оператор CLOSE Оператор отсоединяет файл от устройства В/В и закрывает это устройство. CLOSE([UNIT = ] u [, ERR = err] [, IOSTAT = iostat] & [, STATUS | DISPOSE | DISP = status]) Описание параметров u, err и iostat см. в разд. 11.1. status - символьное выражение, вычисляемое с одним из следующих значений: • 'KEEP' или 'SAVE' - файл сохраняется; • 'DELETE' - файл удаляется; • 'PRINT' - файл подается на печать и сохраняется (только для последовательных файлов); • 'PRINT/DELETE' - файл подается на печать и удаляется (только для последовательных файлов); • 'SUBMIT' - расщепляет процесс для исполнения файла; • 'SUBMIT/DELETE' - расщепляет процесс для исполнения файла и удаляет его после завершения операций. По умолчанию действует статус 'DELETE' для scratch-файлов и окон QuickWin. Для остальных файлов действует 'KEEP'. Задание STATUS = 'KEEP' для временных файлов вызывает ошибку выполнения. Для других видов файлов по умолчанию принимается статус 'KEEP'. Если к устройству не был подсоединен файл, то никакой ошибки не возникает. Открытые файлы не обязательно закрывать оператором CLOSE. При нормальном завершении программы они закрываются автоматически в соответствии с заданными для них статусами. Закрытие устройства (файла) 0 автоматически пересоединяет это устройство к клавиатуре и экрану. 361 О. В. Бартеньев. Современный ФОРТРАН Закрытие устройств 5 и 6 пересоединяет эти устройства соответственно к клавиатуре и экрану. Оператор CLOSE(*) вызовет ошибку компиляции. Пример: ! Закрываем устройство 7 и удаляем с диска подсоединенный к нему файл close(7, status = 'delete') 11.6. Оператор READ Оператор выполняет передачу данных из подсоединенного к устройству u файла в указанные в списке ввода переменные. В CVF в случае прямого файла READ изменяет ассоциируемую переменную файла, указанную в соответствующем операторе OPEN. Передача данных выполняется до тех пор, пока не выполнены все операции ввода либо не возникли ситуации "конец файла" или ошибки. В случае ввода под управлением списка ввод прекращается при обнаружении в поле ввода слеша (/). При вводе из файла или с клавиатуры оператор имеет вид: READ([UNIT = ] u [, [[FMT = ] fmt] | [[NML = ] nml] & [, ADVANCE = advance] [, END = end] [, EOR = eor] & [, ERR = err] [, IOSTAT = iostat] [, REC = rec] [, SIZE = size]) [iolist] При работе с клавиатурой оператор можно записать так: READ * | fmt [, iolist] Если спецификатор UNIT= опущен, то параметр u должен быть первым параметром оператора. Если опущены спецификаторы FMT или NML, то параметры fmt или nml должны быть вторыми параметрами оператора. В противном случае параметры могут появляться в произвольном порядке. u - устройство В/В (разд. 10.2 и 10.3). Устройство может быть задано звездочкой (*). В таком случае ввод будет выполняться с клавиатуры. Если устройство не было подсоединено к файлу, то при чтении будут выполнены действия, задаваемые оператором: OPEN(u, FILE = ' ', STATUS = 'OLD', & ACCESS = 'SEQUENTIAL', FORM = form) где form вычисляется со значениями 'FORMATTED' (при форматном вводе) и 'UNFORMATTED' (при неформатном). Если имя файла включено в запускающую программу командную строку, то это имя будет использовано для имени файла. В противном случае программа попросит ввести имя файла с клавиатуры. fmt - спецификатор формата, которым может быть либо метка оператора FORMAT, либо символьное выражение, содержащее заключенный в круглые скобки список дескрипторов преобразований. При управляемом списком вводе в качестве fmt используется звездочка (*). Управляемый списком ввод возможен только из последовательных текстовых файлов. При неформатном или двоичном вводе параметр fmt должен быть опущен. |