Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. [SOLVED] QFile::size() always returns 0, even when it shouldn't
Forum Updated to NodeBB v4.3 + New Features

[SOLVED] QFile::size() always returns 0, even when it shouldn't

Scheduled Pinned Locked Moved General and Desktop
13 Posts 4 Posters 10.9k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • P Offline
    P Offline
    pwizard
    wrote on last edited by
    #1

    About a "week ago":http://qt-project.org/forums/viewthread/31519 I described a function in my application that invokes mysqldump. That part works great but now I'm having trouble determining if the dump operation succeeded.

    I'm using QFile::size to check the filesize on the output file created by the dump. If the dump operation succeeded, the file should contain text data. If the dump failed (for instance, because the user entered the wrong password) QProcess still creates the output file but it would be empty, i.e. 0 bytes in size. I could then mark the bad file for deletion.

    Unfortunately, QFile::size always returns zero even if the size is checked when the file is open ("output" is a QFile object created higher up in the function):

    @

    /* See if the dump was successful by checking output file size. If the file size is zero,
       it's safe to assume the file is empty and the dump failed.
    */
    qint64 size=0;
    
    if(output.open(QFile::ReadOnly| QIODevice::Text)){
    size = output.size();
    cout << "file size: " << size << endl;
    output.close();
    }
    
    QMessageBox m;
    
    if(size==0){
        m.critical(this,"RoboJournal","Output operation failed.");
        return false;
    }
    
    m.information(this,"RoboJournal","Output operation succeeded.");
    return true;
    

    @

    I'm not sure why this is happening. I've eliminated the possibility of it being because the QFile object doesn't exist when instantiated because QFile::size() returns 0 even when I overwrite an existing file. This code is being built against Qt 4.8 on Linux.

    Is this even the best way to check the success of the mysqldump operation?

    1 Reply Last reply
    0
    • S Offline
      S Offline
      SergioDanielG
      wrote on last edited by
      #2

      Hi pwizard.
      Did you tray errorString() to verify if there are same error with file?
      @
      if(output.open(QFile::ReadOnly| QIODevice::Text)){
      size = output.size();
      cout << "file size: " << size << endl;
      output.close();
      }
      else{
      cout << output.errorString() << endl;
      }
      @

      Hope its util.
      Regad

      www.ftatv.com.ar El foro argentino de la TV libre

      1 Reply Last reply
      0
      • P Offline
        P Offline
        pwizard
        wrote on last edited by
        #3

        @
        cout << output.errorString().toStdString() << endl;
        @

        outputs "Unknown error".

        At this point, I know the app is at least trying to open the file because the app prints the cout << "file size: " << size << endl; string.

        1 Reply Last reply
        0
        • P Offline
          P Offline
          pwizard
          wrote on last edited by
          #4

          I just tried creating another QFile object with the same path as "output" just in case Qt couldn't tell that the original file had changed. Unfortunately, it didn't work--size() is still returning 0.

          1 Reply Last reply
          0
          • P Offline
            P Offline
            pwizard
            wrote on last edited by
            #5

            I'm still trying to solve this and I just noticed something very strange:

            If I call QFile::size directly, it works ("dump" is a QFile):

            i.e.
            @cout << "File size: " << dump.size() << " bytes. " << endl;@

            outputs

            File size: 38080 bytes.

            However, dump.size() always returns 0 if I bind it to a variable before using it:

            i.e.

            @qint64 size=dump.size();
            cout << "File size: " << size << " bytes. " << endl;
            @

            outputs

            File size: 0 bytes.

            The output should be identical but it's not. Could this be a bug in Qt or is something else going on here?

            1 Reply Last reply
            0
            • C Offline
              C Offline
              chenjie4255
              wrote on last edited by
              #6

              what file do you wanted to open ,are you sure your file could be open succeed? or the file is existed?

              1 Reply Last reply
              0
              • JKSHJ Offline
                JKSHJ Offline
                JKSH
                Moderators
                wrote on last edited by
                #7

                Hi,

                [quote author="pwizard" date="1381094564"]I'm still trying to solve this and I just noticed something very strange:

                If I call QFile::size directly, it works ("dump" is a QFile):

                i.e.
                @cout << "File size: " << dump.size() << " bytes. " << endl;@

                outputs

                File size: 38080 bytes.

                However, dump.size() always returns 0 if I bind it to a variable before using it:

                i.e.

                @qint64 size=dump.size();
                cout << "File size: " << size << " bytes. " << endl;
                @

                outputs

                File size: 0 bytes.[/quote]That does look strange. I haven't been able to reproduce it on my PC though (Qt 5.1.1, Windows 7 64-bit, MSVC 2010, 32-bit) -- I created a file that's 38080 bytes long and QFile gave me the correct size when I tried to query it in different ways.

                My first thought was that it could be to do with file caching/flushing, but your QFile is only reading and not writing, so that's unlikely to be the cause.

                Some things you can try, to help pinpoint the issue:

                • See if the issue exists on both debug and release builds
                • Convert your result to a regular int instead of qint64 before printing
                • Print to qDebug() instead of std::cout
                • Read the size without opening the file
                • Upgrade to Qt 4.8.5 or Qt 5.1.1

                A possible workaround:

                • Do QFile::readAll() and check the size of the QByteArray instead

                [quote]Is this even the best way to check the success of the mysqldump operation?[/quote]I would check for error messages from mysqldump directly.

                Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                1 Reply Last reply
                0
                • P Offline
                  P Offline
                  pwizard
                  wrote on last edited by
                  #8

                  bq. what file do you wanted to open ,are you sure your file could be open succeed? or the file is existed?

                  For now, I'm writing these files to /tmp on Linux Mint 15 (anything can read/write in /tmp so I'm using it for debugging purposes). I know these files are good because I can read them with no problem whatsoever in a text editor. The app is being built against the Qt 4.8 in the Mint repositories.

                  bq. Do QFile::readAll() and check the size of the QByteArray instead

                  I just tried that and QByteArray::size() also returns 0. I also tried QByteArray::isEmpty() and that returns true even when a file has text in it.

                  Could this have something to do with the operating system?

                  bq. Convert your result to a regular int instead of qint64 before printing

                  already tried, made no difference.

                  bq. Read the size without opening the file

                  Size still returns 0.

                  bq. Upgrade to Qt 4.8.5 or Qt 5.1.1

                  I'm stuck with the 4.8.4 version in the Mint repositories for now. The app currently doesn't build with Qt5. I suppose I could port the app ahead of schedule if I really had to.

                  bq. See if the issue exists on both debug and release builds

                  Issue affects them both.

                  1 Reply Last reply
                  0
                  • JKSHJ Offline
                    JKSHJ Offline
                    JKSH
                    Moderators
                    wrote on last edited by
                    #9

                    [quote author="pwizard" date="1381176221"][quote]Do QFile::readAll() and check the size of the QByteArray instead[/quote]

                    I just tried that and QByteArray::size() also returns 0. I also tried QByteArray::isEmpty() and that returns true even when a file has text in it.

                    Could this have something to do with the operating system?[/quote]Aha, now we're getting warmer.

                    Has mysqldump fully flushed and closed the file before you tried to check the file size? The data could still be in the operating system's cache, and hasn't been fully written to disk.

                    Try this:

                    Make a dump

                    Then, use an external text editor to open the file and verify that everything has been written

                    AFTER verifying, close the file, launch another program and call QFile::size() -- I'm quite sure you should see the correct size now

                    Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                    1 Reply Last reply
                    0
                    • P Offline
                      P Offline
                      pwizard
                      wrote on last edited by
                      #10

                      You are right...I tested a file that has been in my /tmp since yesterday and QFile::Size() returned the correct value.

                      It looks like the problem is due to the file size being checked prematurely (before mysqldump is finished with it). Is there a reliable way to have QProcess force my program to wait until the file has been completely written to disk/flushed before checking the file size?

                      1 Reply Last reply
                      0
                      • JKSHJ Offline
                        JKSHJ Offline
                        JKSH
                        Moderators
                        wrote on last edited by
                        #11

                        I'm not 100% sure, but I think all file buffers are flushed when the process exits normally. You could wait till your QProcesses has exited (i.e. when it emits the finished() signal, or when waitForFinished() returns) before reading the file.

                        Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                        1 Reply Last reply
                        0
                        • P Offline
                          P Offline
                          pwizard
                          wrote on last edited by
                          #12

                          Attaching a slot to QProcess::finished() did the trick, thanks for the help!

                          I also needed to use QProcess::WaitforFinished() to force the app to wait. Without that, the function would end before QProcess could emit the finished signal (preventing the slot from working).

                          1 Reply Last reply
                          0
                          • JKSHJ Offline
                            JKSHJ Offline
                            JKSH
                            Moderators
                            wrote on last edited by
                            #13

                            [quote author="pwizard" date="1381354862"]Attaching a slot to QProcess::finished() did the trick, thanks for the help![/quote]You're welcome :) Please edit your original post and add "[SOLVED]" to your title.

                            [quote]I also needed to use QProcess::WaitforFinished() to force the app to wait. Without that, the function would end before QProcess could emit the finished signal (preventing the slot from working). [/quote]Sounds like your QProcess is a local variable?

                            Generally you would allocate a QObject on the heap so that it doesn't get destroyed before it can emit all its signals. This way, you can reuse the object too. Call QObject::deleteLater() when you don't need it anymore.

                            Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                            1 Reply Last reply
                            0

                            • Login

                            • Login or register to search.
                            • First post
                              Last post
                            0
                            • Categories
                            • Recent
                            • Tags
                            • Popular
                            • Users
                            • Groups
                            • Search
                            • Get Qt Extensions
                            • Unsolved