Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QStream data serialization problem



  • I'm trying to write a data serializer for some presistent data. I'm using an example from "mimec.org":http://http://www.mimec.org/node/348

    Here is the write startup code:
    @
    bool openForWriting()
    {
    if (false == m_file.open( QIODevice::WriteOnly | QIODevice::Truncate ))
    {
    LOG_ERROR("openForWriting(): '%s'' not opened!!!", QByteArray(QString(m_file.fileName()).toUtf8()).data());

            return false;
        }
    
        m_stream.setDevice( &m_file );
        m_stream.setVersion( QDataStream::Qt_4_8 );
    
        m_stream << MagicHeader;
        m_stream << CurrentVersion;
    
        m_dataVersion = CurrentVersion;
    
        return true;
    }
    

    @

    For now I'm calling this and then closing the file. If the file already exists, then the end result is a zero (0) length file. If I erase the file first, then it works correctly. In my file open I'm asking that an existing file be truncated to zero (0) length, that should have it restart as a zero length file. Is there a problem with truncating a file? Do I need to delete the file explicitly before I start writing, or maybe I need to seek to zero first?

    Also, I'm printing our the file size @m_file.size()@ and the values that I get are basically garbage.

    Any insights will be greatly appreciated.


  • Lifetime Qt Champion

    Hi,

    Are you sure the file is properly closed ? What version of Qt on what OS are you using ?



  • First, I'm running on Qt4.8 Embedded on a BeagleBone Black Angstrom Linux.

    Second, I thought that I was properly closed, I open the file for reading on startup and I print out some messages in the routine that calls close() on the file and I'm seeing the messages so I assumed that the close() call was working.

    I commented out the file read on startup and the write works with an existing zero length file.

    Here is the code that opens for reading:

    @
    bool openForReading()
    {
    if (false == m_file.open( QIODevice::ReadOnly ))
    {
    LOG_ERROR("openForReading(): '%s'' not opened!!!", QByteArray(QString(m_file.fileName()).toUtf8()).data());

            return false;
        }
    
        m_stream.setDevice( &m_file );
        m_stream.setVersion( QDataStream::Qt_4_8 );
    
        qint32 header;
        m_stream >> header;
    
        if ( header != MagicHeader )
        {
            LOG_ERROR("openForReading(): '%s'' bad MagicHeader!!!", QByteArray(QString(m_file.fileName()).toUtf8()).data());
    
            return false;
        }
    
        qint32 version;
        m_stream >> version;
    
        if ( version < MinimumVersion || version > CurrentVersion )
        {
            LOG_ERROR("openForReading(): '%s'' Bad Version:%d!!!", QByteArray(QString(m_file.fileName()).toUtf8()).data(), version);
    
            return false;
        }
    
        m_dataVersion = version;
    
        return true;
    }
    

    @

    For a zero length file the test on the MagicHeader fails and then exits.

    Here is the close() code:

    @
    void close()
    {
    LOG_INFO("WorkingData bytes to write %d", m_file.bytesToWrite());
    LOG_INFO("WorkingData save file size %d", m_file.size());

        m_file.close();
    
        m_dataVersion = -1;
    }
    

    @

    And here is the code that calls everything on startup:

    @
    void loadWorkingData(void)
    {
    if (false == workingDataSave->openForReading())
    {
    LOG_WARNING("WorkingData save file not found!!!");

            workingDataSave->close();
        }
        else
        {
            workingDataSave->stream() >> workingData;
    
            workingDataSave->close();
        }
    }
    

    @

    So if the openForReading() call fails, I call the close() routine that then prints out the messages and calls close() on the file.

    I'll try rearranging things to see if I can get it to work.



  • I added the file close() call into the openForReading() routine where it returns false with no change in behavior, the write still fails for an existing zero length file.


  • Lifetime Qt Champion

    One thing that might also come in play is that you set the same device again and again on m_stream which is never reseted so there might be an initialization problem there



  • Very good point, I'll look into it.

    Thanks,

    Greg



  • I tried setting the stream device to 0 after closing the device but that didn't have any effect.

    I then changed the code to create a new dataserializer and therefore a new stream every time I load or save data and that seems to have done the trick, thanks for the tip.

    Greg


Log in to reply