Read Binary Data into a QVector
-
wrote on 10 Mar 2017, 08:40 last edited by BadHombre 3 Oct 2017, 08:51
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()); -
wrote on 10 Mar 2017, 08:44 last edited by
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
-
wrote on 10 Mar 2017, 09:03 last edited by BadHombre 3 Oct 2017, 09:04
@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 -
@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 valueswrote on 10 Mar 2017, 09:13 last edited by VRonin 3 Oct 2017, 09:25@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
-
wrote on 10 Mar 2017, 09:17 last edited by
the .bin File was created by Matlab and contains only numbers
-
wrote on 10 Mar 2017, 09:25 last edited by
@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
-
wrote on 10 Mar 2017, 09:32 last edited by
@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)));
-
wrote on 10 Mar 2017, 09:36 last edited by
the code I posted above should work then
-
@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)));
@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.
-
wrote on 10 Mar 2017, 09:54 last edited by
@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
-
wrote on 10 Mar 2017, 10:00 last edited by
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');wrote on 10 Mar 2017, 10:06 last edited by@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
-
@VRonin now i get the right number ... what was the Problem ? Is it possible to get the right numbers without changing the matlab code ?
wrote on 10 Mar 2017, 10:30 last edited by VRonin 3 Oct 2017, 10:39@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; } }
1/17