Возможна ли разработка приложения на Octave с GUI? |
Программирование
3.4.2 Обработка двоичных файлов
Двоичный файл, как и текстовый открывается с помощью функции . Разница в том, что в параметре вместо буквы должна использоваться буква (от слова — двоичный): и т.д.
Чтение из двоичного файла осуществляется с помощью обращения к функции
= fread;, где — идентификатор файла, — количество считываемых из файла элементов, — тип считываемых из файла элементов.
Возможные значения параметра приведены в табл. 3.5.
Параметр type | Размер(байт) | Описание |
uchar | 1 | Целое число без знака () |
schar | 1 | Целое со знаком () |
int16 | 2 | Целое со знаком () |
int32 | 4 | Целое со знаком () |
int64 | 8 | Целое со знаком |
uint16 | 2 | Целое без знака () |
uint32 | 4 | Целое без знака () |
uint64 | 8 | Целое без знака () |
float32 | 4 | Вещественное число () |
float64 | 8 | Вещественное число () |
Функция считывает из предварительно открытого файла с идентификатором элементов типа и записывает их в массив (матрицу) , количество реально читанных элементов возвращается в переменной . Если при обращении к функции отсутствует параметр , то подразумевается что из двоичного файла будут считываться значения типа (однобайтовое целое без знака). Если пропущен и параметр , то в массив будут считываться все значения до конца файла. Параметр может быть представлен в виде , в этом случае данные считываются в матрицу размером .
Файл — последовательная структура данных. После открытия файла доступен первый элемент, хранящийся в файле. После чтения очередной порции данных указатель файла смещается на следующую порцию данных.
Текущая позиция указателя файла (смещения от начала файла в байтах) возвращается функцией ftell, здесь — идентификатор уже открытого с помощью файла.
Для перемещения указателя в начало файла служит функция frewind(f );
Функция fseek; обеспечивает все остальные перемещения указателя файла. Функция перемещает текущую позицию в файле с идентификатором на байт относительно позиции .
Параметр может принимать одно из следующих значений:
- строка или число -1 определяет смещение относительно начала файла, в этом случае значение может быть только положительным;
- строка или число 1 определяет смещение относительно конца файла на байтов назад, в этом случае значение также должно быть положительным;
- строка или число 0 определяет смещение относительно текущей позиции на байтов вперёд или назад .
Запись в двоичный файл осуществляется с помощью функции = fwrite, где — идентификатор файла, — массив (матрица) значений, — тип записываемых в файл элементов.
Функция записывает в заранее открытый файл с идентификатором массив , и возвращает количество реально записанных в файл значений .
Рассмотрим несколько примеров работы с двоичными файлами.
Пример 3.14. Создать двоичный файл abc.dat, куда записать целое число , а затем вещественных чисел.
Решить эту задачу можно двумя способами:
- Записать в файл целое число , а затем в цикле вещественных чисел.
- Записать в файл целое число , а затем одним оператором записать в файл массив из вещественных чисел.
Решение задачи с комментариями обоими способами представлено в листинге 3.16.
% Первый способ _________________________
N=input(’N=’); % Ввод значения переменной N.
f=fopen(’abc.dat’, ’wb’); % Открытие двоичного файла abc.dat
% в режиме
записи2Если файл abc.dat не существовал, он создастся, если существовал — все его содержимое будет утеряно. (Прим. редактора).
fwrite(f, N, ’int16’); % Запись числа N в двоичный файл abc.dat.
for i =1:N % Цикл для ввода N вещественных чисел и записи их в файл
x=input(’X=’); % Ввод очередного вещественного числа x.
fwrite(f, x, ’float32’); % Запись очередного числа x в файл.
end;
fclose(f); % Закрытие файла.
% Второй способ _________________________
N=input(’N=’); % Ввод значения переменной N.
f=fopen(’abc.dat’, ’wb’); % Открытие двоичного файла для записи.
fwrite(f, N, ’int16’); % Запись числа N в двоичный файл abc.dat.
for i =1:N % Цикл для ввода массива из N вещественных чисел.
x ( i )=input(strcat(’x(’, int2str(i), ’)=’ ) ); % Ввод очередного
% вещественного числа в массив x.
end;
fwrite(f, x, ’float32’); % Запись массива x в двоичный файл abc.dat.
fclose(f); % Закрытие файла.
Листинг
3.16.
Запись числа в двоичный файл (пример 3.14).
В результате будет сформирован двоичный файл размером байт. Запустим любую из этих программ на выполнение в командной строке, введём и сформируем файл abc.dat размером 82 байта.
Пример 3.15. Считать данные из файла abc.dat, сформированного в задаче из примера 3.14 в массив вещественных чисел.
Программа решения этой задачи представлена в листинге 3.17.
f=fopen(’abc.dat’, ’rb’);% Открытие файла abc.dat в режиме чтения. N=fread(f, 1, ’int16’); % Чтение числа N из двоичного файла abc.dat. x=fread(f, N, ’float32’); % Чтение массива из N вещественных чисел % из двоичного файла abc.dat fclose(f); % Закрытие файла.Листинг 3.17. Чтение данных из файла в массив (пример 3.15).
Пример 3.16. Считать данные из файла abc.dat, сформированного в задаче из примера 3.14 в матрицу вещественных чисел.
Зная, что в файле abc.dat хранится 20 чисел, в качестве примера запишем их в матрицу размером . Программа решения этой задачи представлена в листинге 3.18. В результате работы этой программы будет сформирована матрица вещественных чисел .
f=fopen(’abc.dat’, ’rb’); % Открытие файла abc.dat в режиме чтения. N=fread(f, 1, ’int16’); % Чтение числа N из двоичного файла abc.dat. G=fread(f, [4 5], ’float32’); % Чтение матрицы вещественных чисел % G(4, 5) из двоичного файла abc.dat. fclose(f); % Закрытие файла. >>> G G = 1.20000 9.00000 7.40000 8.90000 5.40000 3.40000 0.10000 6.50000 0.90000 4.30000 5.60000 9.20000 5.60000 8.70000 3.20000 7.80000 8.30000 7.80000 6.50000 2.10000Листинг 3.18. Чтение данных из файла в матрицу (пример 3.15).
Отдельную задачу представляет чтение данных из двоичного файла, если заранее не известно количество элементов в файле. В листинге 3.19 представлена программа, с помощью которой можно создать файл вещественных чисел.
N=input(’N=’); % Ввод значения переменной N. f=fopen(’abc2.dat’, ’wb’);% Открытие файла abc2.dat в режиме записи. for i =1:N % Цикл для ввода N вещественных чисел и записи их в файл. x=input(’X=’);% Ввод очередного вещественного числа x. fwrite(f, x, ’float32’); % Запись числа x в файл abc2.dat. end; fclose(f);Листинг 3.19. Создание двоичного файла с вещественными числами
Отличие этой программы от представленных в листингах 3.17 и 3.18 состоит в том, что оличество записанных в файл abc2.dat вещественных чисел в нём не хранится. Поэтому чтение данных из такого файла осуществляется несколько иначе. Известно, что функция возвращает текущее положение указателя файла. Если с помощью функции передвинуть указатель в конец файла, а затем обратиться к функции , можно вычислить количество байт в файле. Разделив полученное число на 4 (размера вещественного числа типа ), получим количество элементов в файле, после чего считаем нужное количество элементов в массив с помощью функции .
Программа, реализующая описанные выше действия, представлена в листинге 3.20.
f=fopen(’abc2.dat’, ’rb’);% Открытие файла abc2.dat в режиме чтения. fseek(f, 0, 1); % Перевод указателя в конец файла. N= ftell(f) / 4; % Вычисляем количество байт в файле и делим на размер % одного элемента, для float32 это число 4 frewind(f); % Переводим указатель на начало файла x=fread(f, N, ’float32’); % Чтение из файла abc2.dat в массив x N чисел. fclose(f);% Закрытие файла.Листинг 3.20. Чтение из двоичного файла неизвестного размера
Аналогичным образом можно будет считать данные любого типа из двоичного файла. Отличие будет состоять только в том, что в операторе N=ftell(f)/4; необходимо заменить число 4 на действительный размер элементов, хранящихся в файле и при обращении к функции указать в качестве третьего параметра реальный тип считываемых данных. Функция не считает больше элементов, чем находится в файле, независимо от того, что указано во втором параметре. Поэтому, если в листинге 3.20 оператор вычисления записать следующим образом N=ftell(f), то программа будет корректно считывать данные в массив любого типа. Будет происходить следующее: оператор x=fread(f,N,type) попытается считать элементов из двоичного файла, но не считает значений больше, чем их там есть, и остановится в конце файла.