Низкоуровневые функции ввода-вывода файлов позволяют больше всего контролировать чтение или запись данных в файл. Однако эти функции требуют, чтобы вы указывали более подробную информацию о файле, чем более простые в использовании функции высокого уровня, такие как 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
страница с описанием.