Низкоуровневые функции ввода-вывода файлов позволяют больше всего контролировать чтение или запись данных в файл. Однако эти функции требуют, чтобы вы указывали более подробную информацию о файле, чем более простые в использовании функции высокого уровня, такие как importdata. Для получения дополнительной информации о функциях высокого уровня, которые читают текстовые файлы, смотрите Импорт текстовых файлов.
Если функции высокого уровня не могут импортировать ваши данные, используйте одно из следующего:
fscanf, который считывает форматированные данные в текстовом или ASCII-файле; то есть файл, который можно просмотреть в текстовом редакторе. Для получения дополнительной информации см. раздел Чтение данных в форматированный шаблон.
fgetl и fgets, который считывает по одной линии файла за раз, где символ новой строки разделяет каждую строку. Для получения дополнительной информации смотрите Построчное чтение данных.
fread, который считывает поток данных на байтовом или битовом уровне. Для получения дополнительной информации смотрите Импорт бинарных данных с низкоуровневыми вводами-выводами.
Для получения дополнительной информации смотрите:
Примечание
Низкоуровневые функции ввода-вывода файлов основаны на функциях в ANSI® Стандартная библиотека C. Однако MATLAB® включает векторизованные версии функций для чтения и записи данных в массив с минимальными циклами управления.
Чтобы импортировать текстовые файлы, которые importdata и textscan не может читать, рассмотрите использование fscanf. The fscanf функция требует, чтобы вы описали формат вашего файла, но включает много опций для этого описания формата.
Например, создайте текстовый файл mymeas.dat как показано. Данные в mymeas.dat включает повторные наборы значений времени, дат и измерений. Текст заголовка включает количество наборов измерений, N:
Measurement Data N=3 12:00:00 01-Jan-1977 4.21 6.55 6.78 6.55 9.15 0.35 7.57 NaN 7.92 8.49 7.43 7.06 9.59 9.33 3.92 0.31 09:10:02 23-Aug-1990 2.76 6.94 4.38 1.86 0.46 3.17 NaN 4.89 0.97 9.50 7.65 4.45 8.23 0.34 7.95 6.46 15:03:40 15-Apr-2003 7.09 6.55 9.59 7.51 7.54 1.62 3.40 2.55 NaN 1.19 5.85 5.05 6.79 4.98 2.23 6.99
Как и в случае с любыми низкоуровневыми функциями ввода-вывода, перед чтением откройте файл с fopen, и получить идентификатор файла. По умолчанию fopen открывает файлы для доступа к чтению с разрешением 'r'.
Когда вы закончите обработку файла, закройте его с fclose(.fid)
Опишите данные в файле со спецификаторами формата, такими как '%s' для текста, '%d' для целого числа или '%f' для числа с плавающей запятой. (Полный список спецификаторов см. в разделе fscanf страница с описанием.)
Чтобы пропустить буквальные символы в файле, включите их в описание формата. Чтобы пропустить поле данных, используйте звездочку ('*') в спецификаторе.
Для примера рассмотрим линии заголовка mymeas.dat:
Measurement Data % skip the first 2 words, go to next line: %*s %*s\n
N=3 % ignore 'N=', read integer: N=%d\n
% go to next line: \n
12:00:00
01-Jan-1977
4.21 6.55 6.78 6.55
...Чтобы считать заголовки и вернуть одно значение для N:
N = fscanf(fid, '%*s %*s\nN=%d\n\n', 1);
По умолчанию fscanf повторно применяет описание формата до тех пор, пока оно не не будет соответствовать описанию данных или оно не достигнет конца файла.
Опционально задайте количество считываемых значений, чтобы fscanf не пытается считать весь файл. Для примера, в mymeas.datкаждый набор измерений включает фиксированное количество строк и столбцов:
measrows = 4; meascols = 4; meas = fscanf(fid, '%f', [measrows, meascols])';
Существует несколько способов хранения mymeas.dat в рабочем пространстве MATLAB. В этом случае считайте значения в структуру. Каждый элемент структуры имеет три поля: mtime, mdate, и meas.
Примечание
fscanf заполняет массивы числовыми значениями в порядке столбца. Чтобы массив выхода совпадал с ориентацией числовых данных в файле, транспонируйте массив.
filename = 'mymeas.dat';
measrows = 4;
meascols = 4;
% open the file
fid = fopen(filename);
% read the file headers, find N (one value)
N = fscanf(fid, '%*s %*s\nN=%d\n\n', 1);
% read each set of measurements
for n = 1:N
mystruct(n).mtime = fscanf(fid, '%s', 1);
mystruct(n).mdate = fscanf(fid, '%s', 1);
% fscanf fills the array in column order,
% so transpose the results
mystruct(n).meas = ...
fscanf(fid, '%f', [measrows, meascols])';
end
% close the file
fclose(fid);MATLAB обеспечивает две функции, которые считывают линии из файлов и хранят их как векторы символов: fgetl и fgets. The fgets функция копирует линию вместе с символом новой строки в выход, но fgetl не делает.
Следующий пример использует fgetl для чтения всего файла по одной линии за раз. Функция litcount определяет, является ли заданная последовательность символов (literal) появляется в каждой линии. Если это так, функция печатает всю линию, столько раз, сколько литерал появляется в линии.
function y = litcount(filename, literal)
% Count the number of times a given literal appears in each line.
fid = fopen(filename);
y = 0;
tline = fgetl(fid);
while ischar(tline)
matches = strfind(tline, literal);
num = length(matches);
if num > 0
y = y + num;
fprintf(1,'%d:%s\n',num,tline);
end
tline = fgetl(fid);
end
fclose(fid);Создайте файл входных данных с именем badpoem:
Oranges and lemons, Pineapples and tea. Orangutans and monkeys, Dragonflys or fleas.
Чтобы узнать, сколько раз 'an' появляется в этом файле, вызов litcount:
litcount('badpoem','an')
Это возвращает:
2: Oranges and lemons,
1: Pineapples and tea.
3: Orangutans and monkeys,
ans =
6Когда вы считываете фрагмент ваших данных за раз, вы можете использовать feof чтобы проверить, достигли ли вы конца файла. feof возвращает значение 1 когда указатель на файл находится в конце файла. В противном случае возвращается 0.
Примечание
Открытие пустого файла не перемещает индикатор положения файла в конец файла. Считывайте операции и fseek и frewind functions, перемещает индикатор положения файла.
Когда вы используете textscan, fscanf, или fread для чтения фрагментов данных за раз используйте feof чтобы проверить, достигли ли вы конца файла.
Например, предположим, что гипотетический файл mymeas.dat имеет следующую форму, без информации о количестве наборов измерений. Считайте данные в структуру с полями для mtime, mdate, и meas:
12:00:00 01-Jan-1977 4.21 6.55 6.78 6.55 9.15 0.35 7.57 NaN 7.92 8.49 7.43 7.06 9.59 9.33 3.92 0.31 09:10:02 23-Aug-1990 2.76 6.94 4.38 1.86 0.46 3.17 NaN 4.89 0.97 9.50 7.65 4.45 8.23 0.34 7.95 6.46
Чтобы считать файл:
filename = 'mymeas.dat';
measrows = 4;
meascols = 4;
% open the file
fid = fopen(filename);
% make sure the file is not empty
finfo = dir(filename);
fsize = finfo.bytes;
if fsize > 0
% read the file
block = 1;
while ~feof(fid)
mystruct(block).mtime = fscanf(fid, '%s', 1);
mystruct(block).mdate = fscanf(fid, '%s', 1);
% fscanf fills the array in column order,
% so transpose the results
mystruct(block).meas = ...
fscanf(fid, '%f', [measrows, meascols])';
block = block + 1;
end
end
% close the file
fclose(fid);Если вы используете fgetl или fgets в цикле управления, feof не всегда является лучшим способом проверки конца файла. В качестве альтернативы рассмотрите проверку, является ли значение таким fgetl или fgets Возвраты являются вектором символов.
Для примера - функция litcount описывается в Построчное Чтение Данных включает следующее while цикл и fgetl вызовы:
y = 0;
tline = fgetl(fid);
while ischar(tline)
matches = strfind(tline, literal);
num = length(matches);
if num > 0
y = y + num;
fprintf(1,'%d:%s\n',num,tline);
end
tline = fgetl(fid);
endЭтот подход является более устойчивым, чем проверка ~feof(fid) по двум причинам:
Если fgetl или fgets найти данные, они возвращают вектор символов. В противном случае они возвращают число (-1).
После каждой операции чтения, fgetl и fgets проверьте следующий символ в файле для маркера конца файла. Поэтому эти функции иногда устанавливают индикатор конца файла, прежде чем они возвращают значение -1. Для примера рассмотрите следующий трехстрочный текстовый файл. Каждая из первых двух линий заканчивается символом новой строки, а третья линия содержит только маркер конца файла:
123 456
Три последовательных вызова для fgetl дают следующие результаты:
t1 = fgetl(fid); % t1 = '123', feof(fid) = false t2 = fgetl(fid); % t2 = '456', feof(fid) = true t3 = fgetl(fid); % t3 = -1, feof(fid) = true
Это поведение не соответствует спецификациям ANSI для связанных функций языка C.
Схемы кодирования поддерживают символы, необходимые для конкретных алфавитов, таких как для японских или европейских языков. Общие схемы кодирования включают в себя US-ASCII или UTF-8.
Если вы не задаете схему кодирования при открытии файла для чтения, fopen использует автоматическое обнаружение набора символов для определения кодировки. Если вы не задаете схему кодирования при открытии файла для записи, fopen по умолчанию использует UTF-8 в порядок для обеспечения совместимости между всеми платформами и локалями без потери или повреждения данных.
Чтобы определить значение по умолчанию, откройте файл и вызовите fopen снова с синтаксисом:
[filename, permission, machineformat, encoding] = fopen(fid);
Если вы задаете схему кодирования, когда открываете файл, следующие функции применяют эту схему: fscanf, fprintf, fgetl, fgets, fread, и fwrite.
Полный список поддерживаемых схем кодирования и синтаксис определения кодировки см. в fopen страница с описанием.