Main Content

Write and Read Binary Files

Create a binary file with a custom header using the dsp.BinaryFileWriter System object. Write data to this file. Read the header and data using the dsp.BinaryFileReader System object.

Write the Data

Specify the file header as a structure with the following fields:

  • DataType set to double.

  • Complexity set to false.

  • FrameSize (number of rows in the data matrix) set to 150.

  • NumChannels (number of columns in the data matrix) set to 1.

Create a dsp.BinaryFileWriter object using this header. The object writes the header first, followed by the data, to ex_file.bin. The data is a noisy sine wave signal. View the data in a time scope.

L = 150;
header = struct('DataType','double',...
    'Complexity',false,...
    'FrameSize',L,...
    'NumChannels',1);
writer = dsp.BinaryFileWriter('ex_file.bin',...
    'HeaderStructure',header);

sine = dsp.SineWave('SamplesPerFrame',L);
scopewriter = timescope('YLimits',[-1.5 1.5],...
    'SampleRate',sine.SampleRate,...
    'TimeSpanSource','Property',...
    'TimeSpan',1);

for i = 1:1000
    data = sine() + 0.01*randn(L,1);
    writer(data);
    scopewriter(data)
end

Release the writer so that the reader can access the data from this file.

release(writer);

Read the Data

Read the data from the binary file, ex_file.bin, using the dsp.BinaryFileReader object. The file contains the header data followed by the actual data. The object reads the binary data until the end of file is reached. Specify the header to the reader using the HeaderStructure property of the reader object.

If the exact header is not known on the reader side, you must at least specify the prototype of the header. That is, the number of fields, and the data type, size, and complexity of each field in the prototype must match with the header data written to the binary file. When the readHeader function reads the data from the binary file, the function extracts the header information based on how the fields are specified in the header prototype. For example, a header field set to 'double' on the writer side can be specified as any string of 6 characters on the reader side. The readHeader function reads this field as a string of 6 characters from the binary file, which matches with 'double'.

headerPrototype = struct('DataType','datype',...
    'Complexity',false,...
    'FrameSize',1,...
    'NumChannels',10);
reader = dsp.BinaryFileReader(...
    'ex_file.bin',...
    'HeaderStructure',headerPrototype);
headerReader = readHeader(reader)
headerReader = 

  struct with fields:

       DataType: 'double'
     Complexity: 0
      FrameSize: 150
    NumChannels: 1

The header data extracted by the readHeader function is assigned to the corresponding properties of the reader object.

reader.IsDataComplex = headerReader.Complexity;
reader.DataType = headerReader.DataType;
reader.NumChannels = headerReader.NumChannels;
reader.SamplesPerFrame = headerReader.FrameSize;

Initialize a scope on the reader side to view the extracted binary file data.

scopereader = timescope('YLimits',[-1.5 1.5],...
    'SampleRate',sine.SampleRate,...
    'TimeSpanSource','Property',...
    'TimeSpan',1);

The data is read into a single channel (column) containing multiple frames, where each frame has 150 samples. View the data in a time scope.

while ~isDone(reader)
    out = reader();
    scopereader(out)
end
release(reader);
release(scopereader);

Set the reader to read data in frames of size 300. Verify that the data read matches the data written to the file.

reader.SamplesPerFrame = 300;
while ~isDone(reader)
    out = reader();
    scopereader(out)
end
release(reader);

Even when the reader reads data with a different frame size, the output in both time scopes matches exactly.

See Also

|

Related Topics