Write Stream Binary Header with different precisions

3 views (last 30 days)
I want to write a stream binary file that has different precisions for the header. Below is the header that I want to include with 256 Characters for the name of the file, double precision for the number of rows and columns, and then the data set is single precision.
256 Character -> "Unformatted file version=292498251"
Double -> "13"
Double -> "1000000"
Single -> "data" which is an array with 1000000 x 13 entries
Any help would be appreciated!

Answers (2)

dpb
dpb on 28 Sep 2024
Edited: dpb on 28 Sep 2024
Use fwrite with the 'precision' optional argument
str='Unformatted file version=292498251'; % string as char() array
N=100000; M=13;
data=rand(N,M);
fid=fopen('filename.bin','w');
fwrite(fid,'char*1',pad(str,256));
fwrite(fid,[N M],'double');
fwrite(fid,data,'single');
fid=fclose(fid);
clear fid

Umar
Umar on 28 Sep 2024

Hi @Jaden Hoechstetter,

You mentioned, “ _I want to write a stream binary file that has different precisions for the header. Below is the header that I want to include with 256 Characters for the name of the file, double precision for the number of rows and columns, and then the data set is single precision.256 Character -> "Unformatted file version=292498251"Double -> "13"Double -> "1000000"Single -> "data" which is an array with 1000000 x 13 entries,Any help would be appreciated!_ ”

Please see my response to your comments below.

To achieve the objective of writing a stream binary file with different precisions for the header in MATLAB, create string of 256 characters, followed by two double precision numbers and a dataset of single precision numbers with dimensions 1000000 x 13. Then, use MATLAB's file I/O functions to open a binary file for writing, write the header and the dataset to the binary file in the specified format and make sure that the file is properly closed after writing. Here is the complete MATLAB code that implements the above steps:

% Define the Header
headerString = 'Unformatted file version=292498251'; % Initial string
headerString = pad(headerString, 256); % Pad to 256 characters
numRows = 1000000; % Number of rows
numCols = 13; % Number of columns
% Generate the Data
data = single(rand(numRows, numCols)); % Create a 1000000 x 13 array of   
single precision random numbers
% Open a Binary File
fileID = fopen('output_binary_file.bin', 'wb'); % Open file for writing in 
binary  mode
if fileID == -1
  error('Failed to open the file for writing.');
end
% Write the Header and Data
% Write the header string (256 characters)
fwrite(fileID, headerString, 'char');
% Write the number of rows and columns (double precision)
fwrite(fileID, numRows, 'double');
fwrite(fileID, numCols, 'double');
% Write the data (single precision)
fwrite(fileID, data, 'single');
% Close the File
fclose(fileID);
% Display final results
disp('Binary file written successfully with the following contents:');
disp(['Header: ', headerString]);
disp(['Number of Rows: ', num2str(numRows)]);
disp(['Number of Columns: ', num2str(numCols)]);
disp(['Data Size: ', num2str(size(data))]);

Please see attached.

So, in the above code example provided,header string is initialized and padded to ensure it is exactly 256 characters long. This is crucial for maintaining the structure of the binary file. A dataset of random numbers is created using rand, which generates values between 0 and 1. The single function converts these values to single precision. Then fopen function is utilized which opens a binary file named output_binary_file.bin for writing. The 'wb' mode indicates that the file is opened for writing in binary format and Error handling is included to ensure that the file opens successfully. The fwrite function is used to write the header string, followed by the two double precision numbers (number of rows and columns), and finally the dataset of single precision numbers and fclose function is called to close the file, ensuring that all data is flushed and the file is properly saved. Finally, script concludes by displaying the contents of the header, the number of rows and columns, and the size of the data array to confirm that the operations were successful.

For more information on file functions used in the code above, please refer to

fopen

fwrite

<https://www.mathworks.com/help/matlab/ref/fclose.html?s_tid=doc_ta fclose >

Hope this should help resolve your problem. Please let us know if you have any further questions.

  6 Comments
Umar
Umar on 29 Sep 2024
Hi @dpb,
First, let me tell you as a friend that your advice on certain posts in the past has always been helpful. Again, thank you for your detailed feedback regarding the use of data casting with the fwrite function. I appreciate your insights into the complexities of performance optimization, especially in relation to modern CPU architectures and memory management.
Your point about the internal conversion that fwrite performs based on specified precision is well taken. It is indeed prudent to avoid unnecessary explicit casts, particularly when they may not yield significant performance benefits. As you rightly noted, optimizing code without a clear understanding of its context can lead to complications rather than improvements.
I also agree that leveraging MATLAB's built-in tools, such as tall arrays, can often provide effective solutions for handling large datasets without resorting to more intricate optimizations prematurely.
Your perspective on pre-optimization resonates strongly with me; focusing on default settings until a performance issue arises is a sensible approach.
Thank you once again for your thoughtful analysis. Your expertise adds considerable value to our discussions. I hope OP accepts your answer.
dpb
dpb on 29 Sep 2024
"...you must specify the desired precision explicitly to fwrite anyway, and it will do the conversion internally based on that input. "
which -all fwrite
built-in (/MATLAB/toolbox/matlab/iofun/fwrite) /MATLAB/toolbox/matlab/serial/@serial/fwrite.m % serial method /MATLAB/toolbox/instrument/instrument/@i2c/fwrite.m % i2c method /MATLAB/toolbox/shared/instrument/@icinterface/fwrite.m % icinterface method
The iofun base version is builtin so can't easily tell if it has sufficient preprocessing up front to know it doesn't need a cast if the input precision matches the argument class or whether it foregoes testing upfront overhead and "does its thang" regardless...either way, it's generally quite a fast operation so in reality the cost penalty would probably never be noticed; just a case of trying to minimize code that isn't specifically required as a exercise in parsimony...

Sign in to comment.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!