======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//.