Unsolved Read Binary Data into a QVector
-
Hi Guys,
I need some help with reading a binary Data into a vector of doubles :/
This is my Code :
QString filename = "C:/Qt/Test/test.bin"; QFile file1(filename); if (!file1.open(QIODevice::ReadOnly)) return; QByteArray data = file1.readAll(); qDebug() << data.size(); QDataStream ds(&data, QIODevice::ReadWrite); QVector<double> outVect; outVect.resize(data.size()); ds.readRawData((char*)outVect.data(), data.size()); foreach (double current, outVect) qDebug() << current;
My Problem is that i only get 0 :/ and i don't know why --- has sb an idea ?
Maybe it has sth to do with the line :
ds.readRawData((char*)outVect.data(), data.size()); -
What is the format of the file? Binary is the most generic description I can think of
Good place to start http://www.bogotobogo.com/Qt/Qt5_QFile_Serialization.php
-
@VRonin thanks for the link :) it's almost the same i have done in my code except the copy intoa vector of double... and thats where i don't know how to do it :/
the format is a .bin File ... if you open the file with the editor you can see some random ASCII code.. which describes some double values -
@BadHombre said in Read Binary Data into a QVector:
thanks for the link :) it's almost the same i have done in my code except the copy intoa vector of double
No, it's not I'm afraid. It most definitely is not.
the format is a .bin File
still meaningless. How is it saved? by who?
let's try:
QFile file1("C:/Qt/Test/test.bin"); QVector<double> outVect; if (file1.open(QIODevice::ReadOnly)){ QDataStream fileStream(&file1); for(;;){ double tempValue; fileStream.startTransaction(); fileStream >> tempValue; if(fileStream.commitTransaction()) outVect << tempValue; else break; } }
but it's pure speculation until we know what the file contains.
If you really have no idea and the file is not too big you can open it in a hex editor and paste the results here so we can try and guess what's in there
-
the .bin File was created by Matlab and contains only numbers
-
@BadHombre Getting warmer, can you post the matlab code that created it?
-
Without seeing more,
I would suggest
union
union { double f; unsigned char chr; } u;
this should do the trick as long as you pass the correct byteArrey/length.
code: untested from my side
-
@VRonin so i tested your code but i don ' t get the right values :/
matlab code : matrix_save=[A' B' C D' E' ]; fileID = fopen('folder/filename.bin','w'); fwrite(fileID,matrix_save','double'); fclose(fileID);
this is the code i wrote for c++ .. A B C D E are some Matrix..with numbers in it
ifstream file("E:\\file.bin"); char * buffer; long size; file.seekg(0, std::ios::end); size = file.tellg(); file.seekg(0, std::ios::beg); buffer = new char[size]; file.read(buffer, size); file.close(); double* double_values = (double*)buffer;//reinterpret as doubles vector<double> buffer2(double_values, double_values + (size / sizeof(double)));
-
the code I posted above should work then
-
@BadHombre
I totally missed, that you're using<fsteam>
You could also use this code sample:
ifstream file("E:\\file.bin"); double read; if ( file) { file.read( reinterpret_cast<char*>( &read ), sizeof read ); qDebug() << read; }
If MatLap has the same byteorder of course :)
Edit, I acutally found the Source, from when i was researching that.
-
@VRonin doesn't work :/
this are the values in the Qvector
0 0 3.1568e-58 -3.03415e-298 2.08159e+74 2.92534e+211 -2.01411e+84 3.21098e+39 0 0
and this are the numbers from matlab which it should have :/
0 0 -5,99983766238420 -5,99651426671551 -5,22786749086602 5,99821019538431 5,99832392614572 5,22649512993718 0 0
-
If you can temporarily change the matlab file with from
fwrite(fileID,matrix_save','double');
tofwrite(fileID,matrix_save','b');
and see if it works in that case? -
@VRonin I get an error
Error using fwrite
Invalid precision.Error in Untitled (line 28)
fwrite(fileID,matrix_save','b'); -
@BadHombre my bad, I deleted an argument by mistake, I meant
fwrite(fileID,matrix_save','double','b');
-
@VRonin now i get the right number ... what was the Problem ? Is it possible to get the right numbers without changing the matlab code ?
-
the
b
paramter tells matlab to write inBig-endian ordering
-
@BadHombre said in Read Binary Data into a QVector:
what was the Problem ?
@J-Hilk is super correct!
Is it possible to get the right numbers without changing the matlab code ?
Yes and no. If your matlab code and your program are assured to run on the same system and you know the default byte order of that system yes.
if you know your system is big-endian then my original code will just work, if you know your system is little endian (like in your case) add
fileStream.setByteOrder(QDataStream::LittleEndian);
before thefor(;;)
There is no way with your current matlab code to make the file readable in another system without a doubt
EDIT
Actually you can hack your way around the "you know the default byte order of that system" but there is no way out of the "your matlab code and your program are assured to run on the same system" part
bool is_big_endian() { union { quint32 i; char c[4]; } bint = {0x01020304}; return bint.c[0] == 1; }
QFile file1("C:/Qt/Test/test.bin"); QVector<double> outVect; if (file1.open(QIODevice::ReadOnly)){ QDataStream fileStream(&file1); if(!is_big_endian()) fileStream.setByteOrder(QDataStream::LittleEndian); for(;;){ double tempValue; fileStream.startTransaction(); fileStream >> tempValue; if(fileStream.commitTransaction()) outVect << tempValue; else break; } }