c++qtsizeqfile

Qt QFile::size() always returns 0


I'm writing an app where I'm calling QFile::size() method a lot of times. It works in all but one place. I'll show that place and one which works for comparison.

WHICH DOESN'T WORK:

while(!in.atEnd())
{
    if (fileOut.size() != 0) //This "if" isn't executed. (if I change != to == it always returns 0)
    {
      out<<endl;
      qDebug() << "Size of fileOut: " << fileOut.size(); 
    }

    QString temp;
    temp = in.readLine();
    out<<temp;
}

WHICH WORK:

if(fileOut.size() != 0) 
{
  out<<endl;
}

QString temp = in.readLine();
out<<temp<<endl;

temp = in.readLine();
out<<temp;

while(temp[temp.length()-1] != ']')
{
    temp = in.readLine();
    out<<temp;
}

I was looking for a solve but I've tried all of those ways to solve this.

EDIT/SOLVED: For the sake of clarity, everything revolves around the buffor, however, after a slight analysis of the documentation, I can explain why only this piece of code did not return the correct value of QFile::size() and not all (none of them did not reach the size where the buffer would release the data automatically) . In all those places, endl was used and as the documentation says: Writes '\ n' to the stream and flushes the stream. So now everything is clear. In all other places, the flush() method was called, but I did not know about it. Such a short correction. Problem is solved, all you need to do is call flush().


Solution

  • I assume you are using some streamer to write your file. The problem is that the streamer buffers the data, it is not written immediately to the file (it usually waits until the buffer reaches some size to write it down).

    The QFile::pos may not reflect the correct size neither, since it doesn't consider the data still in the buffer but not flushed to the file.

    If you flush() your streamer you'll have the correct size and cursor position:

    #include <qdebug.h>
    #include <qfile.h>
    #include <qtextstream.h>
    
    int main(int argc, char* argv[])
    {
      QFile f("example.txt");
      qDebug() << "f.size() before opening =" << f.size(); // correct
    
      if (!f.open(QFile::WriteOnly)) {
        qDebug() << "Error: not opened!";
        return 1;
      }    
    
      QTextStream out(&f);
      qDebug() << "f.size() before writing =" << f.size(); // 0: file was overwritten
    
      out << "Hello world!\n";
      qDebug() << "f.size() after writing =" << f.size(); // may be incorrect
      qDebug() << "f.pos() after writing =" << f.pos(); // may be incorrect
    
      out.flush();
      qDebug() << "f.size() after flushing =" << f.size(); // correct
    
      f.close();
      qDebug() << "f.size() after closing =" << f.size(); // correct
    
      return 0;
    }
    

    The next example shows an even worse situation, when you may have a non-zero size but that doesn't reflect the correct one:

    #include <qdebug.h>
    #include <qfile.h>
    #include <qtextstream.h>
    
    int main(int argc, char* argv[])
    {
      QFile f("example.txt");
    
      if (!f.open(QFile::WriteOnly)) return 1;
    
      QTextStream out(&f);
    
      for (int i = 0; i < 10000; ++i) { // 10000 works for me, may be you have to increase it to see the partial write
        out << "Hello world!\n";
      }
      qDebug() << "f.size() after writing =" << f.size(); // may be incorrect
      qDebug() << "f.pos() after writing =" << f.pos(); // may be incorrect
    
      out.flush();
      qDebug() << "f.size() after flushing =" << f.size(); // correct
    
      f.close();
    
      return 0;
    }
    

    This is due to the fact mentioned above: the buffer was flushed at some point but there is some data still to be written.

    Again, to be sure, flush your stream before checking the size.


    UPDATE: code available at https://github.com/cbuchart/stackoverflow/blob/master/50669271-qt-qfilesize-always-returns-0/main.cpp