[SOLVED] Deserializing QFile into QVector<double> fails



  • Hi!

    I know how to serialize and deserialize a QVector by following these descriptions http://qt-project.org/doc/qt-4.8/qdatastream.html#details
    And it works. Qt can put doubles into a file and read them back just fine.

    Now I have a binary file that contains a series of doubles which was created by a Delphi program.
    Its size is about 126KB.

    Reading it into a QByteArray works like this:
    @
    /* Reading the File into a ByteArray works */
    QFile file(fileName);
    if (!file.open(QIODevice::ReadOnly)) return 0;
    QByteArray foo = file.readAll();
    file.close();

    qDebug() << foo.size(); // Output: 128020
    

    @

    When I try to read it into a QVector it fails. No matter what type I choose:
    @
    /* Reading into a QVector<anything> fails */
    QFile file(fileName);
    if (!file.open(QIODevice::ReadOnly)) return 0;
    QDataStream in(&file);
    QVector<quint8> bar;
    in >> bar;
    file.close();

    qDebug() << bar.size();
    

    /* Error Message:

    • ASSERT failure in qAllocMore: "Requested size is too large!", file tools\qbytearray.cpp, line 73
    • Invalid parameter passed to C runtime function.
    • Invalid parameter passed to C runtime function.
    • Error - RtlWerpReportException failed with status code :-1073741823. Will try to launch the process directly
      */
      @

    Ultimately I want to read this File into a QVector<double>.
    For this I have 2 options:

    1. Get the latter code working.
    2. Go through the QByteArray byte by byte and combine each 8 of them to a double.
    3. Do it completely differently.

    My questions are:

    • Why does the reading into a QVector fail, when it works fine with a files I have created myself?

    • How would you snip the QByteArray into doubles? Is there an easy way?

    Kind regards!

    schmaunz



  • I helped myself with this:
    @
    // Open and read binary file contents
    QFile file(fileName);
    if (!file.open(QIODevice::ReadOnly)) return 0;
    QByteArray foo = file.readAll();
    file.close();
    // Discard the 5 byte wide file header
    qint32 i = 4;
    // The first Value will be x
    bool isX = true;
    // Result containers
    QVector<double> x;
    QVector<double> y;
    // Temporary byte array
    QByteArray array;
    while(i < foo.size())
    {
    // forget previous 8 bit
    array.clear();
    // read next 8 bit
    for (quint8 j = 0; j < 8; j++)
    {
    array.append(foo.at(i+j));
    }
    // increment i
    i += 8;
    // get array pointer
    char* b = array.data();
    // reinterpret it to double
    double* d = reinterpret_cast<double*>(b);
    // sort values by x and y
    if (isX)
    {
    x.append(*d);
    isX = false;
    }
    else
    {
    y.append(*d);
    isX = true;
    }
    }
    qDebug() << x << y;
    @

    It works, but it is really really ugly.
    I would be glad, if someone could guide me to a more elegant solution :)

    Thanks in advance!



  • If your double data starts at offset 5 in QByteArray foo you could replace lines 13 through 41 by something like (untested!)
    @double xy = reinterpret_cast<double>(foo.data() + 5);
    int i = 0, n = (foo.size() - 5) / 2 / sizeof(double);
    while (i < n) {
    x.append(xy[i++]);
    y.append(xy[i++]);
    }
    @



  • Tested it is, it works out of the box and I like it :)
    Thank you very much andrep!


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.