Низкоуровневые функции ввода-вывода файлов обеспечивают максимальный контроль над чтением или записью данных в файл. Однако эти функции требуют указания более подробной информации о файле, чем упрощенные высокоуровневые функции, такие как importdata. Дополнительные сведения о функциях высокого уровня, считывающих текстовые файлы, см. в разделе Импорт текстовых файлов.
Если высокоуровневые функции не могут импортировать данные, используйте одно из следующих действий.
fscanf, которая считывает форматированные данные в текстовом или ASCII-файле; то есть файл, который можно просмотреть в текстовом редакторе. Дополнительные сведения см. в разделе Чтение данных в форматированном шаблоне.
fgetl и fgets, которые считывают одну строку файла за раз, где символ новой строки разделяет каждую строку. Дополнительные сведения см. в разделе Построчное чтение данных.
fread, которая считывает поток данных на уровне байта или бита. Дополнительные сведения см. в разделе Импорт двоичных данных с низкоуровневым вводом-выводом.
Для получения дополнительной информации см.:
Примечание
Низкоуровневые файловые функции ввода-вывода основаны на функциях библиотеки ANSI ® Standard C. Однако MATLAB ® включает векторизованные версии функций для чтения и записи данных в массив с минимальными циклами управления.
Импорт текстовых файлов, importdata и textscan не может прочитать, рассмотрите возможность использования fscanf. 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. 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 переместите индикатор положения файла.
При использовании 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 справочная страница.