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.
-
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.
-
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