======Fortran-файлы типа Unformatted====== Файлы типа //Unformatted// создаются программами и программными модулями, написанными на языке //Fortran//. Эти файлы являются бинарными (двоичными) и при этом имеют особую внутреннюю структуру, которая не позволяет считывать и записывать файлы такого типа напрямую (без учета этой структуры) из программ, написанных на других языках (например, //C++//). В расчетном ядре и библиотеках пре- и постпроцессинга системы ФРУНД, написанных на языке //Fortran//, используется ряд файлов типа //Unformatted//: * ''rezr'' --- старый файл с результатами //MBS//-расчета, записывающийся из расчетного модуля (новый файл ''results.mbr'' записывается из ядра //fcore//); * ''rean'' --- файл с результатами анализа, записывается из библиотеки анализа //fanaz// (//fcanaz//) на этапе постпроцессинга; * ''*.bnf'' --- файлы с графиками изменения величин, выбранных для замера при анализе; * и т.д. **???** необходимо добавить остальные виды файлы типа //Unformatted//, использующиеся //Fortran//-модулями ФРУНД **???** =====Структура файлов типа Unformatted===== Файлы типа //Unformatted// отличаются от обычных бинарных файлов наличием определенной внутренней структуры. Содержимое таких файлов разделено на ряд последовательных //блоков//. Один блок --- это набор данных, образующийся в //Unformatted//-файле при вызове очередной функции записи. При чтении содержимое //Unformatted//-файла также считывается целыми блоками (даже если функция чтения пытается считать меньший объем данных, чем тот, который содержится в считываемом блоке). ====Структура Unformatted-файлов GNU Fortran (GFortran)==== В следующей таблице приведена структура //Unformatted//-файла формата //GFortran//. ^ Раздел ^^^ Описание ^ Тип ^ Длина, байт ^^ Значение ^ | Список\\ блоков | Блок 1 | Начальный символ\\ блока | Открывающий символ блока | Число | 4 | 4+L_1+4=L_1+8 | 1<=L_1<=2*10^9((Точное значение максимальной длины блока неизвестно, в таблице приведено ориентировочное значение. Оценку сверху для нее можно получить, исходя из максимальной емкости 4-байтового целого числа со знаком. Она равна 2 147 483 647.)) | | ::: | ::: | Содержимое\\ блока | Данные, хранящиеся в блоке | Массив\\ байт | L_1 | ::: | --- | | ::: | ::: | Конечный символ\\ блока | Завершающий символ блока | Число | 4 | ::: | 1<=L_1<=2*10^9 | | ::: | Блок 2 | Начальный символ\\ блока | ... | ... | 4 | L_2+8 | L_2 | | ::: | ::: | Содержимое\\ блока | ... | ... | L_2 | ::: | --- | | ::: | ::: | Конечный символ\\ блока | ... | ... | 4 | ::: | L_2 | | ::: | ... || ... | ... | ... || ... | | ::: | Блок n | Начальный символ\\ блока | ... | ... | 4 | L_n+8 | L_n | | ::: | ::: | Содержимое\\ блока | ... | ... | L_n | ::: | --- | | ::: | ::: | Конечный символ\\ блока | ... | ... | 4 | ::: | L_n | Таким образом, длина //Unformatted//-файла формата //GFortran// равна:\\ L_{GNU}=sum{i=1}{n}{(L_i+8)}=sum{i=1}{n}{L_i}+8n,\\ где * n --- число блоков, * L_i --- число содержимого i-ого блока. ====Структура Unformatted-файлов Intel Fortran / Fortran PowerStation==== //Unformatted//-файлы, создаваемые программами или программными модулями, скомпилированными с помощью компиляторов //Microsoft Fortran PowerStation// или //Intel Fortran// (с опцией //Use PowerStation I/O Format//, выставленной в ''Yes''; соответствующий ключ компилятора --- ''/fpscomp:ioformat''), отличаются чуть более сложной структурой. В таких файлах содержимое каждого блока разбивается на ряд частей. Каждая часть содержит не более 128 байт данных. В следующей таблице приведена структура //Unformatted//-файла формата //PowerStation//. ^ Раздел ^^^^ Описание ^ Тип ^ Длина, байт ^^^ Значение ^ | Начальный символ |||| Открывающий символ файла | Символ | 1 ||| ''K''\\ (код((Под кодом здесь понимается битовое представление соответствующего символа, записанное в 16-ричной системе счисления.)) ''4B'') | | Список\\ блоков | Блок 1 | Полная часть 1 | Начальный символ\\ полной части | Открывающий символ полной части | Символ | 1 | 1+128+1=130 | 130m_1+l_1+2 | код ''81'' | | ::: | ::: | ::: | Содержимое\\ полной части | Данные, хранящиеся в полной части | Массив\\ байт | 128 | ::: | ::: | --- | | ::: | ::: | ::: | Конечный символ\\ полной части | Завершающий символ полной части | Символ | 1 | ::: | ::: | код ''81'' | | ::: | ::: | Полная часть 2 | ... | ... | ... | ... | 130 | ::: | ... | | ::: | ::: | ... || ... | ... | ... | ... | ::: | ... | | ::: | ::: | Полная часть m_1 | ... | ... | ... | ... | 130 | ::: | ... | | ::: | ::: | Неполная часть\\ (заключительная) | Начальный символ\\ неполной части | Открывающий символ неполной части | Число | 1 | 1+l_1+1=l_1+2 | ::: | 1<=l_1<=128 | | ::: | ::: | ::: | Содержимое\\ неполной части | Данные, хранящиеся в неполной части | Массив\\ байт | l_1 | ::: | ::: | --- | | ::: | ::: | ::: | Конечный символ\\ неполной части | Завершающий символ неполной части | Число | 1 | ::: | ::: | 1<=l_1<=128 | | ::: | Блок 2 | Полная часть 1 | ... | ... | ... | ... | 130 | 130m_2+l_2+2 | ... | | ::: | ::: | Полная часть 2 | ... | ... | ... | ... | 130 | ::: | ... | | ::: | ::: | ... || ... | ... | ... | ... | ::: | ... | | ::: | ::: | Полная часть m_2 | ... | ... | ... | ... | 130 | ::: | ... | | ::: | ::: | Неполная часть\\ (заключительная) | ... | ... | ... | ... | l_2+2 | ::: | ... | | ::: | ... ||| ... | ... | ... ||| ... | | ::: | Блок n | Полная часть 1 | ... | ... | ... | ... | 130 | 130m_n+l_n+2 | ... | | ::: | ::: | Полная часть 2 | ... | ... | ... | ... | 130 | ::: | ... | | ::: | ::: | ... || ... | ... | ... | ... | ::: | ... | | ::: | ::: | Полная часть m_n | ... | ... | ... | ... | 130 | ::: | ... | | ::: | ::: | Неполная часть\\ (заключительная) | ... | ... | ... | ... | l_n+2 | ::: | ... | | Конечный символ |||| Закрывающий символ файла | Символ | 1 ||| '',''\\ (код ''82'') | Таким образом, длина //Unformatted//-файла формата //PowerStation// равна:\\ L_{PS}=1+sum{i=1}{n}{(130m_i+l_i+2)}+1=130sum{i=1}{n}{m_i}+sum{i=1}{n}{l_i}+2(n+1),\\ где * n --- число блоков, * m_i --- число полных частей в i-ом блоке, * l_i --- длина содержимого неполной части в i-ом блоке. =====Работа с файлами типа Unformatted в языке Fortran===== С точки зрения программиста, пишущего программный код на языке //Fortran//, работа с файлами типа //Unformatted// практически ничем не отличается от работы с другими типами файлов (например, текстовыми). Функции по работе с файлами языка //Fortran// обеспечивают поддержку блочной структуры //Unformatted//-файлов. Корректная обработка особенностей, связанных с блоками, в программах, написанных на языках, отличных от языка //Fortran// (например, на языке //C++//), ложится на плечи программиста. ====Открытие и закрытие==== ===Открытие=== Открытие //Unformatted//-файла производится с помощью функции ''OPEN'': * для чтения\\ OPEN(<Файловый идентификатор>, FILE = '<Имя файла>', FORM = 'UNFORMATTED', STATUS = 'OLD') * для записи (или перезаписи)\\ OPEN(<Файловый идентификатор>, FILE = '<Имя файла>', FORM = 'UNFORMATTED', STATUS = 'UNKNOWN') Здесь * ''<Файловый идентификатор>'' --- файловая переменная или номер дескриптора, * ''<Имя файла>'' --- наименование открываемого файла. **Примечание.** При открытии для записи в //Unformatted//-файл формата //PowerStation// записывается открывающий символ. ===Закрытие=== Закрытие //Unformatted//-файла производится с помощью функции ''CLOSE'': CLOSE(<Файловый идентификатор>) **Примечание.** При закрытии записываемого //Unformatted//-файла формата //PowerStation// в него записывается закрывающий символ. ====Запись и чтение==== ===Запись=== Запись очередной порции данных в файл типа //Unformatted// производится с помощью функции ''WRITE'': * запись значений переменных ''<Записываемая переменная 1>'', ''<Записываемая переменная 2>'', ..., ''<Записываемая переменная N>''\\ WRITE(<Файловый идентификатор>) <Записываемая переменная 1>, <Записываемая переменная 2>, ..., <Записываемая переменная N> * запись значений элементов массива ''<Записываемый массив>'' длиной ''<Длина записываемого массива>''\\ WRITE(<Файловый идентификатор>) (<Записываемый массив>(Индекс), <Индекс> = 1, <Длина записываемого массива>) **Примечания.** * При каждом вызове процедуры записи в записываемом файле создается очередной блок, содержимое которого представляет собой последовательность бинарных представлений значений переменных, указанных в качестве параметров к процедуре. * В файлах типа //Unformatted// формата //PowerStation// записываемый блок длиной более 128 байт перед записью разбивается на ряд частей, длина содержимого которых не превышает 128 байт. ===Чтение=== Чтение данных из //Unformatted//-файла производится с помощью функции ''READ'': * чтение значений переменных ''<Считываемая переменная 1>'', ''<Считываемая переменная 2>'', ..., ''<Считываемая переменная M>''\\ READ(<Файловый идентификатор>) <Считываемая переменная 1>, <Считываемая переменная 2>, ..., <Считываемая переменная N> * чтение значений элементов массива ''<Считываемый массив>'' длиной ''<Длина считываемого массива>''\\ WRITE(<Файловый идентификатор>) (<Считываемый массив>(Индекс), <Индекс> = 1, <Длина считываемого массива>) **Примечания.** * Каждое обращение к функции чтения вызывает считывание очередного блока целиком, при этом позиция курсора чтения выставляется на начало следующего блока. * В приведенных примерах предполагается, что M<=N (часть считанного блока может оказаться неиспользованной), а длина считываемого массива не превышает длины записываемого массива. Это правило действует, разумеется, при соблюдении типов данных записанных и считываемых переменных (точнее, длин этих типов данных). ====Вспомогательные процедуры навигации==== При чтении файла типа //Unformatted// можно использовать ряд функций, облегчающих навигацию по такому файлу. Они обеспечивают передвижение позиции курсора чтения с учетом блочной структуры файла типа //Unformatted//. ===Возврат к началу файла=== Возврат началу файла производится с помощью функции ''REWIND'': REWIND(<Файловый идентификатор>) **Примечание.** При возврате к началу файла курсор чтения устанавливается на начало первого блока. ===Возврат к началу предыдущего блока=== Возврат началу предыдущего блока (т.е. перемещение курсора чтения к началу предыдущего блока) производится с помощью функции ''BACKSPACE'': BACKSPACE(<Файловый идентификатор>) =====Замечания по конвертации Unformatted-файлов===== Существующие средства просмотра файлов с графиками (''*.bnf'') величин, выбранных для замера при анализе, предполагают, что эти //Unformatted//-файлы имеют формат //PowerStation//. Таким образом, //GFortran//-версии библиотек ядра (прежде всего, ''libfviv.dll'') формируют файлы с графиками неверного формата. Поэтому после этапа анализа и генерации файлов с графиками требуется конвертация их в формат //PowerStation//.