dsp.BinaryFileWriter - Write data to binary files - MATLAB (original) (raw)
Write data to binary files
Description
The dsp.BinaryFileWriter
System object™ writes multichannel signal data to a binary file. If the header is not empty, then the header precedes the signal data. The object specifies the file name and the structure of the header. The first time you write to the file, the object writes the header, followed by the data. On subsequent calls, the object writes the remaining data. If the header is empty, then no header is written.
The object can write floating-point data and integer data. To write character data and fixed-point data, see Write and Read Character Data and Write and Read Fixed-Point Data. The input data can be real or complex. When the data is complex, the object writes the data as interleaved real and imaginary components. For an example, seeWrite and Read Fixed-Point Data. By default, the writer uses the endianness of the host machine. To change the endianness, you can use the swapbytes function. For an example, see Change Endianness of Data Before Writing.
To write data to a binary file:
- Create the
dsp.BinaryFileWriter
object and set its properties. - Call the object with arguments, as if it were a function.
To learn more about how System objects work, see What Are System Objects?
Creation
Syntax
Description
`writer` = dsp.BinaryFileWriter
creates a binary file writer object, writer
, using the default properties.
`writer` = dsp.BinaryFileWriter(`fname`)
sets the Filename
property to fname
.
`writer` = dsp.BinaryFileWriter(`fname`,`Name=Value`)
sets additional properties using one or more name-value arguments. For example, to specify the name of the binary file as "ex_file.bin", setHeaderStructure
to "ex_file.bin".
Properties
Unless otherwise indicated, properties are nontunable, which means you cannot change their values after calling the object. Objects lock when you call them, and therelease function unlocks them.
If a property is tunable, you can change its value at any time.
For more information on changing property values, seeSystem Design in MATLAB Using System Objects.
Name of the file to which the object writes the data, specified as a character vector or a string scalar. You must specify the full path for the file.
The Filename
property is tunable in generated code, that is, you can pass the name of the binary file as an input while running the code generated from this object. For an example, see Tunable Binary File Name in Generated Code.
Usage
Syntax
Description
writer([data](#d126e245471))
writes data to the binary file in a row-major format. Each call to the algorithm writes the elements ofdata
at the end of the file. At the first call to the algorithm, the object writes the header first, followed by the data. If the header is empty, then no header is written.
The input data can be real or complex. For complex data, real and imaginary parts are interleaved. For example, if the data equals [1 2; 3 4]+1j*[5 6; 7 8]
, then the object writes the elements as 1 5 2 6 3 7 4 8
.
Input Arguments
Data to be written to the binary file in a row-major format, specified as a vector or a matrix. The object writes the data in row-major format. For example, if the input array is [1 2 4 5; 8 7 9 2
], the object writes the data as [1 2 4 5 8 7 9 2
].
The input data can be real or complex. For complex data, real and imaginary parts are interleaved. For example, if the data equals [1 2; 3 4]+1j*[5 6; 7 8]
, then the object writes the elements as [1 5 2 6 3 7 4 8
].
The input can be a variable-size signal, that is, you can change the frame size (number of rows) of the signal during simulation but the number of channels (columns) must remain constant. (since R2025a)
Data Types: single
| double
| int8
| int16
| int32
| int64
| uint8
| uint16
| uint32
| uint64
Complex Number Support: Yes
Object Functions
To use an object function, specify the System object as the first input argument. For example, to release system resources of a System object named obj
, use this syntax:
step | Run System object algorithm |
---|---|
release | Release resources and allow changes to System object property values and input characteristics |
reset | Reset internal states of System object |
Examples
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 todouble
.Complexity
set tofalse
.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.
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.
Use a dsp.BinaryFileReader
System object™ to read data from a binary file in a row-major format.
Write the Data
Write the matrix A
to the binary file Matdata.bin
using a dsp.BinaryFileWriter
object. The object writes the specified header followed by the data.
The header has the following format:
DataType
set todouble
.Complexity
set tofalse
.FrameSize
(number of rows in the data matrix) set to 3.NumChannels
(number of columns in the data matrix) set to 4.
A = [1 2 3 8; 4 5 6 10; 7 8 9 11]; header = struct(DataType="double",... Complexity=false,... FrameSize=3,... NumChannels=4); writer = dsp.BinaryFileWriter("Matdata.bin",... HeaderStructure=header); writer(A);
Release the writer so that the reader can access the data.
Read the Data
Specify the header using the HeaderStructure
property of the reader object. If the exact header is not known, 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. The dsp.BinaryFileReader
object reads the binary file Matdata.bin
until the end of file is reached. Configure the System object to read the data into 4 channels, with each channel containing 5 samples. Each loop of the iteration reads a channel (or frame) of data.
headerPrototype = struct(DataType="double",... Complexity=false,... FrameSize=5,... NumChannels=4); reader = dsp.BinaryFileReader('Matdata.bin',... HeaderStructure=headerPrototype,... NumChannels=4,... SamplesPerFrame=5); while ~isDone(reader) out = reader(); display(out) end
out = 5×4
1 2 3 8
4 5 6 10
7 8 9 11
0 0 0 0
0 0 0 0
Each frame of out
contains frames of the matrix A
, followed by zeros to complete the frame. The original matrix A
contains 4 channels with 3 samples in each channel. The reader is configured to read data into 4 channels, with each channel containing 5 samples. Because there are not enough samples to complete the frame, the reader object appends zeros at the end of each frame.
Create a dsp.BinaryFileWriter
object which writes to a file named myfile.dat
. There is no header. The data is complex.
writer = dsp.BinaryFileWriter("myfile.dat"); data = [1 2 3 4]+1i*[5 6 7 8]; writer(data); release(writer);
Read the data using the dsp.BinaryFileReader
System object™. To view data in the format it is written to the file, set the IsDataComplex
property to false
. The reader object reads the data as a sequence of numbers in a row major format. Set SamplesPerFrame
to 1 and NumChannels
to 8.
reader = dsp.BinaryFileReader("myfile.dat",SamplesPerFrame=1,... NumChannels=8); s = struct([]); reader.HeaderStructure = s; dataRead = reader();
You can see that the real and imaginary components of the original data are sample interleaved.
dataRead = 1×8
1 5 2 6 3 7 4 8
The dsp.BinaryFileWriter
and dsp.BinaryFileReader
System objects do not support writing and reading fixed-point data. As a workaround, you can write the stored integer portion of the fi
data, read the data, and use this value to reconstruct the fi
data.
Write the Fixed-Point Data
Create an fi
object to represent 100 signed random numbers with a word length of 14 and a fraction length of 12. Write the stored integer portion of the fi
object to the data file myFile.dat
. The built-in data type is int16
, which can be computed using class(storeIntData)
.
data = randn(100,1); fiDataWriter = fi(data,1,14,12); storeIntData = storedInteger(fiDataWriter);
writer = dsp.BinaryFileWriter("myFile.dat"); writer(storeIntData);
Release the writer so that the reader can access the data.
Read the Fixed-Point Data
Specify the reader to read the stored integer data as int16
data with 100 samples per data frame. The real-world value of the fixed-point number can be represented using 2(-fractionLength)(storedInteger). If you know the signedness, word length, and fraction length of the fixed-point data, you can reconstruct the fi
data using fi(realValue,signedness,wordLength,fractionLength). In this example, the data is signed with a word length of 14 and a fraction length of 12.
reader = dsp.BinaryFileReader(Filename="myFile.dat",... SamplesPerFrame=100,... DataType="int16"); data = reader(); fractionLength = 12; wordLength = 14; realValue = 2^(-fractionLength)*double(data);
fiDataReader = fi(realValue,1,... wordLength,fractionLength);
Verify that the writer data is the same as the reader data.
isequal(fiDataWriter,fiDataReader)
The dsp.BinaryFileWriter
and dsp.BinaryFileReader
System objects do not support writing and reading characters. As a workaround, cast character data to one of the built-in data types and write the integer data. After the reader reads the data, convert the data to a character using the char
function.
Write the Character Data
Cast a character into uint8
using the cast
function. Write the cast data to the data file myFile.dat
.
data = 'binary_file'; castData = cast(data,'uint8'); writer = dsp.BinaryFileWriter('myFile.dat'); writer(castData);
Release the writer so that the reader can access the data.
Read the uint8
Data
Configure the reader to read the cast data as uint8
data.
reader = dsp.BinaryFileReader('myFile.dat',... DataType='uint8',... SamplesPerFrame=11); readerData = reader(); charData = char(readerData);
Verify that the writer data is the same as the reader data. By default, the reader returns the data in a column-major format.
By default, the dsp.BinaryFileWriter
System object™ uses the endianness of the host machine. To change the endianness, use the swapbytes
function.
Write a numeric array into myfile.dat
using the dsp.BinaryFileWriter
object. Before writing the data, change the endianness of the data using the swapbytes
function.
data = [1 2 3 4 2 2]; swapData = swapbytes(data); writer = dsp.BinaryFileWriter("myfile.dat"); writer(swapData);
Since R2025a
The writeBinaryFile
function writes character data to a file, reads data from the same file, and compares the written data with the read data to verify if they are the same. The function accepts the filename as the input.
function writeBinaryFile(filename)
data = 'test_data'; castData = cast(data,'uint8'); writer = dsp.BinaryFileWriter(Filename=filename); writer(castData); release(writer); reader = dsp.BinaryFileReader(Filename=filename,... DataType='uint8',... SamplesPerFrame=9); readerData = reader(); charData = char(readerData); strcmp(data,charData.')
end
For generating code, specify the filename to be a variable-length character vector of a maximum length of 500.
filename = coder.typeof('a',[1 500],[0 1]);
Generate a MEX file using the codegen
function.
codegen writeBinaryFile -args {filename}
Code generation successful.
Run the MEX file by specifying the filename as an input argument. In this example, the file name is 'myfile.dat'
. You can specify a different filename whenever you run the writeBinaryFile_mex
file.
writeBinaryFile_mex('myfile.dat')
Extended Capabilities
Version History
Introduced in R2016b
The dsp.BinaryFileWriter
object supports variable-size input signals, that is, you can change the frame size (number of rows) of the signal during simulation but the number of channels (columns) must remain constant.
The Filename
property of the dsp.BinaryFileWriter
object is tunable in generated code, that is, you can pass the name of the binary file as an input while running the code generated from this object. For an example, see Tunable Binary File Name in Generated Code.