современный фортран , Бортеньев. О. В. Бартеньев Современный Фортран
Скачать 2.24 Mb.
|
370 11. Операции над внешними файлами iostat - переменная стандартного целого типа. Возвращает 0 при отсутствии ошибок, отрицательное число, если возникла ситуация "конец файла", или номер возникшей ошибки. mode - символьная переменная. Возвращает значения mode или action ('READ', 'WRITE' или 'READWRITE'), заданные для устройства (файла) оператором OPEN. Возвращает 'UNDEFINED' при отсутствии подсоединения. name - символьная переменная. Возвращает при опросе устройства имя подсоединенного к нему файла. Если файл не подсоединен к устройству или если подсоединенный файл не имеет имени, значение переменной name не определено. При опросе файла name возвращает заданное имя файла. named - логическая переменная. Возвращает .TRUE., если файл имеет имя, и .FALSE. - в противном случае. nextrec - переменная стандартного целого типа. Возвращает номер следующей записи в файле прямого доступа. Номер первой записи файла равен единице. num - переменная стандартного целого типа. При опросе файла возвращает номер подсоединенного к файлу устройства. Если к файлу не подсоединено устройство, значение переменной num не определено. При опросе устройства переменная num возвращает номер опрашиваемого устройства. Если задано UNIT = *, то нельзя включать спецификатор NUM- BER. opened - логическая переменная, возвращающая при опросе устройства .TRUE., если какой-либо файл подсоединен к устройству, и .FALSE. - в противном случае. При опросе файла возвращает .TRUE., если файл подсоединен к какому-либо устройству, и .FALSE. - в противном случае. org - символьная переменная, возвращает значение 'SEQUENTIAL', если файл имеет последовательную организацию, 'RELATIVE', если - связанную, или 'UNKNOWN', если процессор не может определить вид организации файла. pad - символьная переменная, возвращающая 'YES', если файл открыт с PAD = 'YES', и 'NO' - в противном случае. position - символьная переменная, возвращающая 'REWIND', если файл позиционирован в своей начальной точке. Возвращает 'APPEND', если файл расположен в своей конечной точке перед записью "конец файла". Возвращает 'ASIS', если файл подсоединен без изменения позиции. Возвращает 'UNDEFINED' при отсутствии подсоединения или если файл подсоединен для прямого доступа. read - символьная переменная, возвращающая 'YES', если файл открыт для чтения, и 'NO', если из файла нельзя вводить данные. Возвращает 'UN- KNOWN', если процессор не может определить, разрешается ли читать из файла. readwrite - символьная переменная, возвращающая 'YES', если файл открыт как для чтения, так и для записи, и 'NO', если нельзя выполнять 371 О. В. Бартеньев. Современный ФОРТРАН чтение или запись. Возвращает 'UNKNOWN', если процессор не может определить, разрешается ли использовать файл и для чтения и для записи. recl - переменная стандартного целого типа. Возвращает длину записи (в байтах) файла прямого доступа. Если файл подсоединен для неформатной передачи данных, возвращаемое число байт зависит от используемой операционной системы. rtyp - символьная переменная. Возвращает одно из перечисленных в разд. 11.4 для спецификатора RECORDTYPE значений, или 'UNKNOWN', если файл или устройство не подсоединены. seq - символьная переменная. Возвращает 'YES', если файл подсоединен для последовательного доступа, и 'NO' или 'UNKNOWN' - в противном случае. share - символьная переменная. Возвращает значение статуса share, заданного файлу оператором OPEN: 'COMPAT', 'DENYRW', 'DENYWR', 'DENYRD' и 'DENYNONE'. При опросе устройства, если к устройству не подсоединен файл, значение переменной share не определено. unformatted - символьная переменная. Возвращает 'YES', если файл открыт для неформатной передачи данных, и 'NO' - в противном случае. Возвращает 'UNKNOWN', если процессор не может определить, какой В/В разрешен. write - символьная переменная, возвращающая 'YES', если файл открыт для записи, и 'NO', если в файл нельзя выводить данные. Возвращает 'UN- KNOWN', если процессор не может определить, допустимо ли выводить в файл данные. Оператор INQUIRE возвращает значение атрибутов, с которыми файл был открыт. Свойства неоткрытых файлов не могут быть возвращены оператором. Если некоторые атрибуты не заданы, то оператор возвращает установленные для них по умолчанию значения. В качестве применяемых в операторе INQUIRE переменных могут быть использованы простые переменные, элементы массивов и компоненты производных типов. Если при опросе устройства ключевое слово UNIT= опущено, то параметр u должен идти первым. Другие параметры могут располагаться в произвольном порядке, но не должны повторяться. Пример: character(25) :: st(25) = ' ' open(1, file = 'a.txt', action = 'write', position = 'append') write(1, *) st rewind 1 inquire(1, name = st(1), action = st(2), blank = st(3), position = st(4)) print *, (trim(st(i)), ' ', i = 1, 4) ! a.txt WRITE NULL REWIND 372 11. Операции над внешними файлами 11.15. Функция EOF Функция возвращает .TRUE., если подсоединенный к устройству u-файл позиционирован на специальной записи "конец файла" или после этой записи. Иначе EOF возвращает .FALSE. Синтаксис функции: flag = EOF(u) u - устройство В/В (разд. 10.2). 11.16. Организация быстрого ввода/вывода Затраты времени на В/В снизятся, если придерживаться следующих правил: 1) по возможности используйте неформатные файлы вместо форматных. Так, вывод в файл, подсоединенный к устройству 10, выполнится значительно быстрее вывода в файл, который подсоединен к устройству 20: real(4), dimension(100, 20) :: array = 1.0 open(10, file = 'a.dat', form = 'unformatted') ! или form = 'binary' open(20, file = 'a.txt', form = 'formatted') write(10) array ! Доступ к файлу a.dat происходит write(20, '(20f8.3)') array ! быстрее, чем к файлу a.txt 2) выполняйте В/В всего массива или всей строки, не используя циклов; 3) если все же при передаче многомерных массивов необходимо организовать вложенные циклы, то применяйте естественный порядок передачи элементов массива: во внутреннем цикле должен изменяться самый левый индекс, а во внешнем - самый правый. Это обеспечит доступ к элементам массива в порядке их размещения в памяти, что, понятно, ускорит передачу данных; 4) используйте, если позволяют ресурсы, для хранения промежуточных результатов оперативную память, а не внешние файлы; 5) применяйте в случае форматного В/В при программировании формата целочисленное выражение вместо символьной строки, поскольку в первом случае формат определяется единожды - при компиляции, а во втором - спецификация формата, строка form, - формируется в процессе исполнения программы: real(4), dimension(1000) :: array integer(4) :: i character(15) :: form ... ! Вычисляется значение переменной n ! Этот способ заданий формата лучше, чем формирование строки form, ! содержащей спецификацию формата ! <n> - выражение в дескрипторе преобразований print '(1x, 373 О. В. Бартеньев. Современный ФОРТРАН write(form, '(a, i5, a)') '(1x', n, 'f8.3)' ! Формируем строку формата form print form, (array(i), i = 1, n) ! Вывод по формату form 6) создавайте условия для декомпозиции используемых в операторах В/В циклических списков. Для этого переменная цикла должна быть целочисленной, не должна быть формальным параметром, принадлежать оператору EQUIVALENCE и обладать атрибутом VOLATILE, а спецификация формата в случае форматной передачи данных не должна иметь целочисленных выражений в дескрипторе преобразований. Пример циклического списка: write(10, '(20f8.3)') (array(i), i = 1, n) ! Циклический список из n элементов Пояснение. Обычно каждый элемент списка В/В обращается к процедурам В/В библиотеки CVF. Временные затраты на эти обращения значительны. С целью их уменьшения неявный цикл замещается компилятором на несколько (до семи) вложенных DO-циклов, использующих для вывода оптимизированную процедуру В/В, которая может осуществлять передачу порциями, содержащими несколько элементов В/В; 7) для увеличения объема передаваемых данных при одном обращении к диску попытайтесь увеличить значение спецификатора BUFFER- COUNT оператора OPEN, но не меняйте значение спецификатора BLOCKSIZE того же оператора, поскольку оно подбирается оптимальным для используемого устройства. Влияние BUFFERCOUNT на скорость передачи данных должно быть установлено экспериментально; 8) не задавайте значение спецификатора RECL оператора OPEN большим, чем размер буфера В/В (этот размер определяется спецификатором BLOCKSIZE), так как передача избыточных данных, незначительно заполняющих буфер, малопроизводительна; 9) значение спецификатора RECL = recl выбирайте таким образом, чтобы буфер В/В заполнялся наилучшим образом. Буфер будет заполнен полностью, если его размер кратен recl или, наоборот, значение RECL кратно размеру буфера, например: размер буфера равен 8192, а в операторе OPEN задан спецификатор RECL = 1024 или RECL = 16384; 10) используйте оптимальный с позиции быстродействия тип записей, задаваемый в операторе OPEN спецификатором RECORDTYPE: • для файлов с последовательной организацией наибольшую производительность обеспечит задание записей фиксированной длины (RECORDTYPE = 'FIXED'); • в случае неформатных файлов последовательной организации используйте записи переменной длины (RECORDTYPE = 'VARIABLE'); 374 11. Операции над внешними файлами • в форматных файлах последовательной организации с записями переменной длины задавайте RECORDTYPE = 'STREAM_LF'. 375 12. Конструктор модулей для объектов ActiveX 12.1. Некоторые сведения об объектах ActiveX Технология использования в приложениях, в том числе и написанных на Фортране, объектов, созданных в других приложениях, называется Автоматизацией, ранее известная как OLE Автоматизация. Сами же созданные в рамках этой технологии объекты называются объектами ActiveX. Доступ к объекту осуществляется при помощи интерфейса или напрямую через таблицу виртуальных функций. Объекты ActiveX поддерживают модель многокомпонентных объектов COM. Интерфейс Автоматизации - это группа взаимосвязанных функций, обеспечивающих доступ к методам и свойствам объекта, а также обработку распознаваемых объектом событий. Метод - это действие, которое может выполнять объект. Свойство - это функция-член, обеспечивающая доступ к информации о состоянии объекта. Большинство свойств имеет две функции доступа - одна возвращает значение свойства, вторая его устанавливает. Событие - это действие, распознаваемое объектом, например щелчок мышью или нажатие клавиши. Событие является методом, вызываемым объектом. В общем случае объект может поддерживать несколько интерфейсов. Указатель на любой из них вернет подпрограмма COMQueryInterface. Приложение, осуществляющее доступ к объектам ActiveX, называется клиентом ActiveX. Сам же объект ActiveX - это экземпляр класса, предоставляющий клиенту ActiveX свои свойства, методы и события. Объекты ActiveX создаются компонентами ActiveX, в качестве которых могут выступать или приложения, или библиотеки. Так, компонентом ActiveX является Microsoft Excel. Как правило, компонент ActiveX предоставляет множество объектов. Например, Excel содержит объект с именем Application (приложение), для инициализации и создания которого в Фортран-приложении потребуется выполнить команды call COMInitialize(status) ! Инициализируем COM и создаем объект Excel call COMCreateObject("Excel.Application.8", excelapp, status) Свойство Visible объекта excelapp изменит команда call $Application_SetVisible(excelapp, .true.) Кроме чисто объектов, компонент ActiveX может предоставлять объекты-наборы, которые в общем случае состоят из различных экземпляров некоторого объекта. Например, Excel может предоставить клиенту ActiveX несколько "Рабочих книг", а в пределах каждой 376 12. Конструктор модулей для объектов ActiveX "Рабочей книги" - несколько "Рабочих листов". Создание объекта-набора "Рабочая книга" обеспечит команда ! Получаем указатель на объект "Рабочая книга" - Workbooks workbooks = $Application_GetWorkbooks(excelapp, $status = status) Экземпляр этого объекта вернет вызов ! Открываем заданный файл. Указываем в качестве параметра имя файла Excel workbook = Workbooks_Open(workbooks, fname, $status = status) 12.2. Для чего нужен конструктор модулей Процедуры, обеспечивающие работу с объектами ActiveX, можно разделить на две группы: 1) процедуры управления объектами. Они применяются со всеми объектами Автоматизации; 2) процедуры, реализующие объекты, их методы и свойства и реагирующие на события. В общем случае подобные процедуры уникальны (как по именам, так и по функциям) для каждого объекта, его метода, свойства или события. Процедуры первой группы реализованы в поставляемых с CVF библиотеках dfcom.lib и dfauto.lib. Для доступа к ним в CVF имеются необходимые интерфейсы. Они нужны, поскольку эти процедуры написаны на СИ. Применяемая в Фортране технология создания интерфейсов в разноязычных приложениях рассмотрена в [1]. Процедуры второй группы описаны в сопровождающей компоненты ActiveX документации. Поэтому, чтобы ими воспользоваться, нужно иметь под рукой необходимые источники информации. Однако перед программирующем на Фортране пользователем, даже имеющим необходимые сведения, возникают серьезные проблемы, связанные с обеспечением доступа к процедурам. Что опять-таки связано с тем, что они реализованы, как правило, не на Фортране. Чтобы облегчить доступ к процедурам второй группы, с CVF поставляется конструктор модулей Visual Fortran Module Wizard (далее - КМ), создающий по имеющейся об объектах информации модули на Фортране, содержащие описания используемых с объектами данных и тексты процедур второй группы. (Информация о процедурах размещена в соответствующих файлах. Так, все данные об объектах Excel находятся в поставляемой с Excel библиотеке Excel8.olb.) Далее мы рассмотрим общие для всех объектов ActiveX процедуры управления Автоматизацией и употребляемые в Автоматизации виды данных. А затем - порядок работы с КМ и разберем пример его применения. 377 О. В. Бартеньев. Современный ФОРТРАН 12.3. Интерфейсы процедур управления Автоматизацией Интерфейсы процедур, имена которых приведены в табл. 12.1, содержатся в файле dfcom.f90. Процедуры обеспечивают инициализацию объекта ActiveX, его создание, активизацию и освобождение. Управление свойствами объекта и вызов связанных с ним методов осуществляется процедурами, приведенными в табл. 12.2. Интерфейсы к ним находятся в файле dfauto.f90. Таблица 12.1. Процедуры, управляющие объектами ActiveX Процедура Назначение Вид COMAddObject Reference Добавляет ссылку на объект Функция типа INTEGER(4) COMCLSIDFrom ProgID Передает программный идентификатор и возвращает соответствующий идентификатор класса Подпрог- рамма COMCLSIDFrom String Передает строку, содержащую идентификатор класса, и возвращает соответствующий идентификатор класса То же COMCreateObject ByGUID Передает идентификатор класса и создает экземпляр объекта. Возвращает указатель на интерфейс объекта " COMCreateObject ByProgID Передает программный идентификатор и создает экземпляр объекта. Возвращает указатель на IDispatch-интерфейс объекта " COMGetActiveObject ByGUID Передает идентификатор класса и возвращает указатель на интерфейс активного в данный момент объекта " COMGetActiveObject ByProgID Передает программный идентификатор и возвращает указатель на IDispatch-интерфейс активного в данный момент объекта " COMGetFileObject Передает имя файла и возвращает указатель на IDispatch-интерфейс объекта Автоматизации, который может обрабатывать файл " COMQueryInterface Передает идентификатор интерфейса и возвращает указатель " COMReleaseObject Освобождает объект Функция типа INTEGER(4) COMInitialize Инициализация COM-библиотеки Подпрог- рамма 378 12. Конструктор модулей для объектов ActiveX COMUninitialize Освобождение COM-библиотеки (последняя вызываемая COM-подпрограмма) То же Таблица 12.2. Процедуры, обеспечивающие управление свойствами объекта и вызовы его методов Процедура Назначение Вид AUTOAddArg Передает имя параметра и значение и добавляет параметр в структуру данных, содержащую список параметров Подпрог- рамма AUTOAllocate InvokeArgs Размещает структуру со списком параметров, которые будут переданы родовой функции AUTOInvoke Функция типа INTEGER(4) AUTODeallocate InvokeArgs Освобождает память, занимаемую структурой со списком параметров Подпрог- рамма AUTOGetExceptInfo Запрашивает данные об исключении, с которым завершился метод То же AUTOGetProperty Передает имя или идентификатор свойства и возвращает значение свойства объекта Автоматизации Функция типа INTEGER(4) AUTOGetProperty ByID Передает ID-имя свойства и возвращает значение свойства объекта Автоматизации То же AUTOGetProperty InvokeArgs Передает структуру со списком параметров и возвращает величину свойства объекта Автоматизации " AUTOInvoke Передает имя идентификатора метода объекта и структуру со списком параметров и вызывает соответствующий метод " AUTOSetProperty Передает имя идентификатора свойства и его величину и устанавливает значение свойства объекта Автоматизации " AUTOSetProperty ByID Передает ID-имя свойства и его величину и устанавливает значение свойства объекта Автоматизации " AUTOSetProperty InvokeArgs Передает структуру со списком параметров и устанавливает заданное значение свойства объекта Автоматизации " |