using fwrite for multiple data type at once
Show older comments
I am trying to write a vector of data of various data types (all numeric) to a .binary file all at once instead of having to loop through the data set. I have a vector that contains the numbers:
myData = [1 3.5 400 75 2.5 6 1];
and then each number has an associated data type:
myDataType = {'single','double','single','single','double','single','single'};
Is there a way to use the fwrite function to write all the data of varying types at once? Such as:
fwrite(fid,myData,myDataType)
This command doesnt work as fwrite. know that for this example that i am giving it would be just as fast to loop through the data and write them to the file one at a time using:
for n = 1:length(myData)
fwrite(fid,nyData(n),myDataType{n})
end
however the data vector i am writing contains thousands of different data and the format of the data type does not follow any particular set pattern and changes. typically, when all the data is the same such as a vector containing 10,000 double values, it is expoenntially faster to write all of the data at once like this:
fwrite(fid,myData,'double')
than it is to use a for loop. But for my specific case, the data types change. Any help would be greatly appreciated.
Accepted Answer
More Answers (1)
dpb
on 22 Jan 2021
0 votes
The precision, skip, machinefmt optional inputs to fwrite have not been vectorized (as you have discovered), so you can't intermix the types with array syntax for the output array.
If you write a file in this fashion, however, not only do you have a problem writing it efficiently, you have also created the problem in being able to read it back efficiently--you'll have to read it record-by-record, too, because fread has the same limitation on what is a vector input.
I would strongly suggest to NOT do this at all: I see some possible alternatives:
- Just write everything as double; if you for some reason your really, really need a given variable to be single, then cast it after reading;
- Reorder the writing to put all of a given type in one call and the rest in another. This also adds more complication that I can see it possibly be being worth in have to sort things out in both directions again,
- SAVE the variables to a .mat file instead. Preserves type at the expense of some overhead but much less painful to code and probably at least as fast as the looping solution to do what is requested.
3 Comments
dpb
on 22 Jan 2021
"not only do you have a problem writing it efficiently, you have also created the problem in being able to read it back efficiently--you'll have to read it record-by-record, too, ..."
Actually, it's even worse than that--you have to write/read every array element individually with its corresponding type unless you parse the dataType array and find where the same type is repeated more than once so that you can write those sequential elements together--and that additional logic to keep track of the position and type probably is more expensive than the savings that would be achieved.
Eric Alexander
on 24 Jan 2021
dpb
on 24 Jan 2021
Shoulda' known/guessed.
The memmapfile idea should work; I don't know about performance; the one time I tried using it was on Q? here for large file input and it was much slower (by about 10X) than directly computing the desired location in the file and using fseek to move around. But, that was a case needing to bring in pieces of a very large file; a sequential write operation might be pretty quick.
Alternatively, this is a place where a Fortran mex file might be a handy way to approach it -- the Fortran i/o system would handle the type information transparently on an unformatted WRITE.
Which brings up the Q? of if the legacy system would happen to be a Fortran application, is it actually a stream file (which required nonstandard compiler extensions before F2003) or a direct access file which would also have the hidden record lengths in it.
Categories
Find more on Floating-Point Specification in MATLAB in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!