В этом примере показано, как создать и использовать два различных системных объектов для облегчения потоковой передачи данных в и из MATLAB ®: TextFileReader
и TextFileWriter
.
Объекты, обсуждаемые в этом примере, касаются ряда реалистичных вариантов использования, и они могут быть настроены для достижения более продвинутых и специализированных задач.
Системные объекты являются классами MATLAB, которые получают из matlab.System
. В результате все системные объекты наследуют общий открытый интерфейс, который включает стандартные методы:
setup
- Инициализируйте объект, обычно в начале симуляции
reset
- Очистить внутреннее состояние объекта, вернув его к статусу постинициализации по умолчанию
release
- Отпустите любые ресурсы (память, оборудование или ресурсы ОС), используемые внутри объекта
Когда вы создаете новые виды системных объектов, вы обеспечиваете определенные реализации для всех предыдущих методов, чтобы определить его поведение.
В этом примере мы обсуждаем внутреннюю структуру и использование следующих двух системных объектов:
TextFileReader
TextFileWriter
Чтобы создать эти Системные объекты для потоковой передачи данных в MATLAB и из него, этот пример использует стандартные низкоуровневые функции ввода-вывода файлов, доступные в MATLAB (например fscanf
, fread
, fprintf
, и fwrite
). Абстрагируя большинство деталей использования этих функций, они стремятся сделать задачу чтения и записи потоковых данных более простой и эффективной.
Этот пример включает использование ряда расширенных конструкций для создания системных объектов. Для получения дополнительной информации об авторских системных объектах см. раздел «Создание системных объектов».
TextFileReader классов
The TextFileReader
класс включает определение класса, общие и частную собственность, конструктор, защищенные методы, переопределенные из matlab.System
базовый класс и частные методы. The TextFileWriter
класс аналогично структурирован.
Определение класса утверждает, что TextFileReader
класс получают из обоих matlab.System
и matlab.system.mixin.FiniteSource
.
classdef (StrictDefaults)TextFileReader < matlab.System & matlab.system.mixin.FiniteSource
matlab.System
является обязательным и базовым классом для всех системных объектов
matlab.system.mixin.FiniteSource
указывает, что этот класс является источником сигнала с конечным количеством выборок данных. Для этого типа класса, в дополнение к обычному интерфейсу, системный объект также предоставляет isDone
функция. Когда isDone
возвращает true, объект достиг конца доступных данных.
Общественная собственность могут быть изменены пользователем, чтобы настроить поведение объекта к его конкретному приложению. TextFileReader
имеет два неотключаемых общедоступных свойства (их можно изменить только перед первым вызовом объекта) и четыре настраиваемых общедоступных свойства. Все общественная собственность имеют значение по умолчанию. Значения по умолчанию присваиваются соответствующим свойствам, если пользователь не задает ничего другого.
properties (Nontunable) Filename = 'tempfile.txt' HeaderLines = 4 end
properties DataFormat = '%g' Delimiter = ',' SamplesPerFrame = 1024 PlayCount = 1 end
Частная собственность не видны пользователю и могут служить ряду целей, включая
Чтобы удерживать значения, вычисленные только иногда, затем используется с последующими вызовами алгоритма. Для примера значения, используемые во время инициализации, когда setup
вызывается или объект вызывается впервые. Это может сэкономить их перевычисление во время выполнения и улучшить эффективность основных функциональных возможностей
Чтобы определить внутреннее состояние объекта. Для примера, pNumEofReached
хранит количество раз, когда был достигнут индикатор конца файла:
properties(Access = private) pFID = -1 pNumChannels pLineFormat pNumEofReached = 0 end
Конструктор определен так, чтобы можно было создать TextFileReader
объект использует пары "имя-значение". Конструктор вызывается, когда новый образец TextDataReader
создается. Вызов setProperties
в конструкторе позволяет устанавливать свойства с парами "имя-значение" при конструкции. В конструкторе не должны задаваться другие задачи инициализации. Вместо этого используйте setupImpl
способ.
methods function obj = TextFileReader(varargin) setProperties(obj, nargin, varargin{:}); end end
matlab.System
Методы, защищенные базовым классомКаждый из общедоступных методов, общих для всех системных объектов, имеет соответствующие защищенные методы, которые они вызывают внутренне. Имена этих защищенных методов все включают в себя Impl
постфикс. Они могут быть реализованы при определении класса, чтобы запрограммировать поведение вашего системного объекта.
Для получения дополнительной информации о соответствии между стандартными открытыми методами и их внутренними реализациями см. Сводные данные последовательности вызовов.
Для примера, TextFileReader
переопределяет эти Impl
методы:
setupImpl
resetImpl
stepImpl
releaseImpl
isDoneImpl
processTunedPropertiesImpl
loadObjectImpl
saveObjectImpl
Частные методы доступны только из других методов того же класса. Они могут использоваться, чтобы сделать остальную часть кода более читаемой. Они также могут улучшить переиспользуемость кода путем группировки под отдельным кодом стандартных программ, который используется несколько раз в различных частях класса. Для TextFileReader
, частные методы создаются для:
getWorkingFID
goToStartOfData
peekCurrentLine
lockNumberOfChannelsUsingCurrentLine
readNDataRows
В этом примере показано, как вы можете использовать TextFileReader
и TextFileWriter
около:
Создание текстового файла, содержащего выборки двух различных синусоидальных сигналов с помощью TextFileWriter
Чтение из текстового файла осуществляется с помощью TextFileReader
.
Создайте новый файл для хранения двух синусоидальных сигналов с частотами 50 Гц и 60 Гц. Для каждого сигнала сохраненные данные состоят из 800 выборок со частотой дискретизации 8 кГц.
Создайте выборки данных:
fs = 8000; tmax = 0.1; t = (0:1/fs:tmax-1/fs)'; N = length(t); f = [50,60]; data = sin(2*pi*t*f);
Сформируйте строку заголовка, чтобы описать данные читаемым способом для будущего использования (необязательный шаг):
fileheader = sprintf(['The following contains %d samples of two ',... 'sinusoids,\nwith frequencies %d Hz and %d Hz and a sample rate of',... ' %d kHz\n\n'], N, f(1),f(2),fs/1000);
Чтобы сохранить сигнал в текстовый файл, создайте TextFileWriter
объект. Конструктор TextFileWriter
необходимо имя целевого файла и некоторые необязательные параметры, которые могут быть переданы в виде пар "имя-значение".
TxtWriter = TextFileWriter('Filename','sinewaves.txt','Header',fileheader)
TxtWriter = TextFileWriter with properties: Filename: 'sinewaves.txt' Header: 'The following contains 800 samples of two sinusoids,...' DataFormat: '%.18g' Delimiter: ','
TextFileWriter
записывает данные в разделенные разделителем ASCII-файлы. Его общественная собственность включают:
Filename
- Имя файла, который будет записан. Если файл с таким именем уже существует, он перезаписывается. Когда начинаются операции, объект начинает запись в файл сразу после заголовка. Затем объект добавляет новые данные при каждом последующем вызове объекта, пока он не будет деблокирован. Выполнение сброса вызова возобновляет запись с начала файла.
Header
- Символьная строка, часто состоящая из нескольких линий и заканчиваемая символом newline (\n
). Это задается пользователем и может быть изменено для встраивания считываемой человеком информации, которая описывает фактические данные.
DataFormat
- Формат, используемый для хранения каждой выборки данных. Это может взять любое значение, присваиваемое в качестве спецификатора преобразования в formatSpec
строка, используемая встроенной функцией MATLAB fprintf
. DataFormat
применяется ко всем каналам, записанным в файл. Значение по умолчанию для этого свойства '%.18g'
, что позволяет сохранить данные двойной точности с плавающей точкой в полной точности.
Delimiter
- Символ, используемый для разделения выборок из различных каналов одновременно. Каждая линия написанного файла преобразуется в момент времени, и она включает в себя столько выборок, сколько предоставлено каналов в качестве входных (другими словами, количество столбцов в матричном входе, переданное объекту).
Чтобы записать все доступные данные в файл, можно использовать один вызов.
TxtWriter(data)
Деблокируйте управление файлом путем вызова release
функция.
release(TxtWriter)
Теперь данные хранятся в новом файле. Чтобы визуально просмотреть файл, введите:
edit('sinewaves.txt')
Поскольку заголовок занимает три линии, данные начинаются в линии 4
.
В этом простом случае длина всего сигнала небольшая, и он удобно помещается на системной памяти. Поэтому данные можно создать все сразу и записать в файл за один шаг.
Бывают случаи, когда такой подход невозможен или практичен. Для примера данные могут быть слишком большими, чтобы помещаться в один Переменный MATLAB (слишком большими, чтобы помещаться в системной памяти). В качестве альтернативы данные могут быть созданы циклически в цикле или переданы в MATLAB из внешнего источника. Во всех этих случаях потоковая передача данных в файл может быть выполнена с помощью подхода, аналогичного следующему примеру.
Используйте потоковый генератор синусоиды, чтобы создать систему координат данных по циклу. Запустите необходимое количество итераций, чтобы создать данные и сохранить их в файле:
frameLength = 32; tmax = 10; t = (0:1/fs:tmax-1/fs)'; N = length(t); data = sin(2*pi*t*f); numCycles = N/frameLength; for k = 1:10 % Long running loop when you replace 10 with numCycles. dataFrame = sin(2*pi*t*f); TxtWriter(dataFrame) end release(TxtWriter)
Чтобы считать из текстового файла, создайте образец TextFileReader
.
TxtReader = TextFileReader('Filename','sinewaves.txt','HeaderLines',3,'SamplesPerFrame',frameLength)
TxtReader = TextFileReader with properties: Filename: 'sinewaves.txt' HeaderLines: 3 DataFormat: '%g' Delimiter: ',' SamplesPerFrame: 32 PlayCount: 1
TextFileReader
считывает числовые данные из ASCII-файлов, разделенных разделителями. Его свойства аналогичны свойствам TextFileWriter
. Далее следуют некоторые различия
HeaderLines
- Количество линий, используемых заголовком в файле, указанном в Filename
. Первый вызов объекта начинает считываться с номера линии HeaderLines+1
. Последующие вызовы объекта продолжают считываться из линии сразу после ранее считанной линии. Вызывающие reset
возобновит чтение из линии HeaderLines+1
.
Delimiter
- Символ, используемый для разделения выборок из различных каналов одновременно. В этом случае разделитель также используется, чтобы определить количество каналов данных, хранящихся в файле. Когда объект запускается впервые, объект подсчитывает количество Delimiter
символы в линии HeaderLines+1
, скажем numDel
. Затем для каждого момента времени объект читается numChan = numDel+1
числовые значения с форматированными DataFormat
. Матрица, возвращенная алгоритмом, имеет размер SamplesPerFrame
-by- numChan
.
SamplesPerFrame
- Количество строк, считанных каждым вызовом объекта. Это значение также является количеством строк матрицы, возвращенной в качестве вывода. При достижении последних доступных строк данных может быть меньше необходимого SamplesPerFrame
. В этом случае доступные данные заполняются нулями, чтобы получить матрицу размера SamplesPerFrame
-by- numChan
. Когда все данные считываются, алгоритм просто возвращается zeros(SamplesPerFrame,numChan)
до reset
или release
вызывается.
PlayCount
- Количество циклических чтений данных в файле. Если объект достигает конца файла, и файл еще не был считан в несколько раз равным PlayCount
, чтение возобновляется с начала данных (линия HeaderLines+1
). Если последние линии файла не обеспечивают достаточное количество выборок, чтобы сформировать полную выходную матрицу размера SamplesPerFrame
-by- numChan
, затем система координат завершается с использованием начальных данных. После чтения файла PlayCount
раз выходная матрица, возвращаемая алгоритмом, заполняется нулями, и все вызовы isDone
возвращает true, если только reset
или release
вызывается. Чтобы просматривать доступные данные бессрочно, PlayCount
может быть задано значение Inf
.
Для чтения данных из текстового файла используется более общий потоковый подход. Этот способ чтения данных также имеет отношение к работе с очень большими файлами данных. Предварительно выделите систему координат данных с frameLength
строки и 2 столбца.
dataFrame = zeros(frameLength,2,'single');
Чтение из текстового файла и запись в двоичный файл, пока данные присутствуют в исходном текстовом файле. Заметьте, как метод isDone
используется для управления выполнением цикла while.
while(~isDone(TxtReader)) dataFrame(:) = TxtReader(); end release(TxtReader)
Этот пример иллюстрировал, как создавать и использовать системные объекты для чтения и записи в файлы числовых данных. TextFileReader
и TextFileWriter
может редактироваться для выполнения специальных операций чтения и записи файлов. Можно также объединить эти пользовательские системные объекты со встроенными системными объектами, такими как dsp.BinaryFileWriter
и dsp.BinaryFileReader
.
Дополнительные сведения об авторских объектах System для пользовательских алгоритмов см. в разделе Создание системных объектов.