Read binary data from file
-
You can use pointers to do this sort of thing. I have an example that takes some part of a QByteArray and extracts an integer from it:
int i; char *c; c = (char*)(&i); // set address of char to point to address of integer. The two are now tied together // indirectly copy bytes to integer. Var 'index' is first byte of integer value in the byte_array for(unsigned int cntr = 0;cntr < sizeof(int);++cntr) *(c + cntr) = array[index + cntr]; // var 'i' now contains integer value
-
Thank you for your response,
indeed I noticed the pointer problem in my code, but even when I use the normal variable, the value returned is not correct :
QDataStream s(&file); s.setByteOrder(QDataStream::LittleEndian); char buffer[4]; s.skipRawData(80); s.readRawData(buffer,4); ulong length = ulong(buffer); qDebug() << length;
Should return 70540 in this case but return 2686300.
Same for :QDataStream s(&file); s.setByteOrder(QDataStream::LittleEndian); char *buffer = new char[4]; s.skipRawData(80); s.readRawData(buffer,4); ulong length = ulong(*buffer); qDebug() << length;
wich return 0...
I would just like to understand what is incorrect in this code to know what I am doing wrong
-
Thank you for your response,
indeed I noticed the pointer problem in my code, but even when I use the normal variable, the value returned is not correct :
QDataStream s(&file); s.setByteOrder(QDataStream::LittleEndian); char buffer[4]; s.skipRawData(80); s.readRawData(buffer,4); ulong length = ulong(buffer); qDebug() << length;
Should return 70540 in this case but return 2686300.
Same for :QDataStream s(&file); s.setByteOrder(QDataStream::LittleEndian); char *buffer = new char[4]; s.skipRawData(80); s.readRawData(buffer,4); ulong length = ulong(*buffer); qDebug() << length;
wich return 0...
I would just like to understand what is incorrect in this code to know what I am doing wrong
@HB76 said in Read binary data from file:
ulong length = ulong(*buffer);
only looks at the first char/byte in
buffer
, i.e.buffer[0]
, and that's probably a 0, so that's not much good!As for
ulong length = ulong(buffer);
not returning what you expect, the first thing I'd do is print it out in hex rather than decimal/look at the 4 bytes and see if they are the wrong way round/not what you expect in the 4 bytes. [I'm tired now, but doesn'tulong(buffer)
just do the same thing as(ulong)buffer
, and hence all you're printing is the address of the variable and nothing about its content?]Apart from that, and I haven't looked up the mechanics, but I don't see how
QDataStream::setByteOrder()
can cooperate with your choice of usingQDataStream::readRawData()
. If it reads raw bytes it's not going to be dealing with numbers and observing any byte ordering. Presumably you have to useQDataStream &QDataStream::operator>>(quint32 &i)
, https://doc.qt.io/qt-5/qdatastream.html#operator-gt-gt-5, if you want to read what you know to be numbers and have the byte order taken into account. -
QDataStream s(&file); s.setByteOrder(QDataStream::LittleEndian); s.skipRawData(80); qint32 value; s >> value; qDebug() << value;
give me the same result, 0...
@HB76 just in case, could you please post:
- the values of the bytes at positions 80, 81, 82, 83 for the file you're working with?
- the size of the data (or the whole file) for such file?
-
I've found a way to do it :
QByteArray data = file.read(4); qint32 facet_count; memcpy(&facet_count, data.constData(), 4); qDebug() << facet_count;
Just for knowledge, why this simple code doesn'y work ?
file.seek(80); ulong length = file.read(4).toULong(); qDebug() << length;
it would be much more simplier..
-
@HB76 said in Read binary data from file:
ulong length = file.read(4).toULong();
Because you did not read the documentation: https://doc.qt.io/qt-5/qbytearray.html#toLong
-
@HB76 said in Read binary data from file:
ulong length = file.read(4).toULong();
Because you did not read the documentation: https://doc.qt.io/qt-5/qbytearray.html#toLong
@Christian-Ehrlicher I was just having a look at it but I supposed I didn't understand the whole explaination the first time as I'm not native english ^^'
-
The example there should be obvious:
QByteArray str("FF"); bool ok; int hex = str.toInt(&ok, 16); // hex == 255, ok == true int dec = str.toInt(&ok, 10); // dec == 0, ok == false
As you can see it converts a string value into an integer
-
@HB76 said in Read binary data from file:
ut why every time the conversion failed with this method whereas the conversion with memcpy is working ?
Again: toUint() interprets your string as ascii text and tries to convert it to an integer, whereas memcpy simply copies the plain data - C basics on how a value is interpreted.