1

I want to read multiple float values from the file in which I already wrote using this:

QDataStream &operator<<(QDataStream &out, const SomeClass &obj)
{
    out << obj.maxX << obj.maxY << obj.minX << obj.minY;

    out << (int) obj.points.size();

    for(int c = 0; c < obj.points.size(); ++c){
        out << obj.points.at(c).floatX << obj.points.at(c).floatY;
    }

    return out;
}

And I can read this file using this:

QDataStream &operator>>(QDataStream &in, SomeClass &obj)
{
    in >> obj.maxX >> obj.maxY >> obj.minX >> obj.minY;

    int pointsSize = 0;
    in >> pointsSize;

    for(int c = 0; c < pointsSize; ++c){

        float x = 0, y = 0;

        in >> x >> y;

        obj.points.push_back(Point(x, y));
    }
    return in;
}

But it's not so efficient to read these floats separately, so I want to read first 4 floats(maxX, maxY, minX, minY) together, then read one int, and then read all other floats(instances of floatX and floatY) together.
I already tried this:

 QDataStream in(&file);
 QByteArray ba;
 in.readRawData(ba.data(), 4*sizeof(float));

 float array[4];
 memcpy(&array, ba.constData(), ba.size());

But it gives wrong result.

So, how can I read many floats in one buffer array or vector?

UPD:

I already saw getline() too, but how exactly can I iterate over char * from binary file and get floats from it?

konstantin_doncov
  • 2,725
  • 4
  • 40
  • 100
  • Is your memcopy backwards with source and destination swapped? [This does not look correct --- memcpy(&array, ba.constData(), ba.size());] – William J Bagshaw Jul 25 '18 at 08:05
  • 1
    Are you sure reading them separately is inefficient? Did you profile it? The way you want to do this adds an additional copy, so I wouldn't be as sure that this is faster. – Karsten Koop Jul 25 '18 at 08:07
  • @WilliamJBagshaw I know that this isn't correct, but I don't know how to fix it in the right way – konstantin_doncov Jul 25 '18 at 08:12
  • @KarstenKoop No, I'm not sure, but I already read somewhere about it, so I want to test this approach – konstantin_doncov Jul 25 '18 at 08:14
  • 1
    Your approach assumes that the data layout (like endianess) in the file and in memory is the same. By using the `QDataStream` operators, you can be sure that this gets taken care of. So I wouldn't do the reading of raw bytes if it can be avoided, and prefer the official functions. – Karsten Koop Jul 25 '18 at 08:31
  • @KarstenKoop thanks, but are you sure that these multiple read operation(>>) is better than one read operation? Anyway, I think that I still need optimization, this code fragment takes the longest time, I understood that this is due to disk i/o operations? but I think I need to speed up this, but how? – konstantin_doncov Jul 25 '18 at 08:38
  • 2
    So I guess the function is not just called once, but millions of times? I don't think that disk i/o makes a difference, as data from disk is cached and buffered in several layers, almost never only 4 bytes will be read from disk. – Karsten Koop Jul 25 '18 at 08:44

1 Answers1

1

From docs:

"The QDataStream class provides serialization of binary data to a QIODevice."

If you use getRawData() method, binary data is what you get. Thats the reason why are you geting wrong results when interpreting them as something else.

If you want to speed things up, my advice would be to dont use QDataStream, and use regular standard fstream instead.

To avoid multiple readings, read whole line using getline() and then iterate over numbers stored in there.

kocica
  • 6,412
  • 2
  • 14
  • 35
  • Thanks for your advice. But I already tried to use ifstream and got wrong result too. Also I tried to search example which is applicable for my task but they also give wrong result, so can you give code sample which I can use? – konstantin_doncov Jul 25 '18 at 08:51
  • Removing the `&` character will make no difference as the address of an array is the same as the address of the first element. – john Jul 25 '18 at 09:12
  • Yes, I already saw getline() too, but how exactly can I iterate over `char *` from binary file and get floats from it? – konstantin_doncov Jul 25 '18 at 09:31
  • Use `fstream` for writing into file so the data wont be saved as binary. Then extracting data from string via `sstringstream` or from `char *` by casting array to `float *` and indexing as usual. `char *data = ...; float *f = (float *)data; float f1 = f[0]` – kocica Jul 25 '18 at 09:47