[Solved] QFile ReadOnly Recreates the File If...



  • Hi all

    I have a problem with QFile. The documentation says

    Note: In WriteOnly or ReadWrite mode, if the relevant file does not already exist, this function  will try to create a new file before opening it.
    

    So i think it is safe to assume, ReadOnly will not create file. Anyways i have this code i created.

    void DataIO::readDataFromFile(QByteArray &outRead, const QString filePath)
    {
        QFile file(filePath);
    
        // @todo This line even if file exists, recreates it
        if(file.exists() && file.open(QFile::ReadOnly) == false)
        {
            return;
        }
    
        outRead = file.readAll();
    
        file.close();
    }
    

    I use it inside MainWindow class' constructor.

    MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
    {
    ui->setupUi(this);
    
    networkConfigurationManager = new QNetworkConfigurationManager(this);
    
    // If network connection is enabled/disabled check again
    connect(networkConfigurationManager, SIGNAL(onlineStateChanged(bool))
            , this, SLOT(onOnline(bool)));
    
    // If there is network connection, close the program
    // @todo This doesn't works if not debugging!
    if(networkConfigurationManager->isOnline() == true)
    {
        this->close();
    }
    
    // Read column headers
    QByteArray tempColumnsByte;
    DataIO::readDataFromFile(tempColumnsByte, HEADERS_PATH);
    
    if(tempColumnsByte.size() != 0)
    {
        QString tempColumns(tempColumnsByte);
        QStringList tempColumnsList = tempColumns.left(tempColumns.lastIndexOf('\n'))
                .split('\n');
    
        m_columnHeaders.swap(tempColumnsList);
        rearrangeColumnHeaders();
    }
    }
    

    This readDataFromFile function works as expected under normal conditions(tested it). But when i use it right after i call this function.

    if(networkConfigurationManager->isOnline() == true)
    {
        this->close();
    }
    
    1. Creates a file if the file doesn't exist.
    2. Recreates a file if the file exists, resulting in destruction of the former file contents

    This is so weird i cant understand one bit.

    A side problem: isOnline() function doesn't works if not debugging. Still messing things up no matter what.

    I use Qt 5.5.0 and Qt Creator 3.4.2



  • Code causing problem may be even not shown.

    But, did you check that you described behavior correctly under debugger?
    file.open(QFile::ReadOnly) should not create a file.
    outRead = file.readAll(); may



  • @alex_malyu said:

    Code causing problem may be even not shown.

    But, did you check that you described behavior correctly under debugger?
    file.open(QFile::ReadOnly) should not create a file.
    outRead = file.readAll(); may

    That line doesn't run if the file doesn't exists or opening fails. So it is safe to assume it wont create a file. I confirmed that code works as expected under normal conditions. That is not the real issue anyways.

    Secondly, only networkConfigurationManager->isOnline() doesn't works unless debugged.

    Also, i just confirmed, even if i read the file or not. If i have networkConfigurationManager->isOnline() line enabled. File gets corrupted no matter what.


  • Moderators

    First of all you've got a logic error in the file handling code

    if(file.exists() && file.open(QFile::ReadOnly) == false)
       return;
    
    outRead = file.readAll();
    

    So if the file doesn't exist the condition will return false and you will try to read the unopened, non-existing file anyway...

    Second, if there's a difference in release/debug behavior it is usually a deployment problem, not code. Check that all the required libraries are deployed and that you are not mixing release/debug libraries.

    Third - not related to the question, but please consider changing your function signature to:

    QByteArray DataIO::readDataFromFile(const QString& filePath)
    

    Returning by value instead of a ref parameter enables RVO, which is a significant performance gain. Similarly, don't pass "in" parameters by const copy. The const makes no difference and the copy is just wasteful. Consider always passing "in" parameters by const reference. That's again a great help to the optimizing compiler.



  • You are calling close() on the widget in the constructor.
    It opens so many ways to screw up.

    Try to comment line below

    // if(networkConfigurationManager->isOnline() == true)

    and check if problem is caused by
    {
    this->close();
    }



  • @Chris-Kawa
    Thanks for pointing that logic error, fixed it now. I have not tested the code after adding file.exists(). So thats a mistake on my side. But the code was working and the same problem was present even then.

    By debugging/debugged i didn't mean debug or release deployment, i meant debugging(GDB/CDB).

    Thanks for the link and optimization ideas. I changed it to the way you suggested.

    But it didn't solved my problem. Thanks for the help anyways.

    @alex_malyu
    Yes, you are right.

    The problem was i overrided close event of MainWindow and inside overrided closeEvent i was writing back the changes.

    1. Inside overrided close event, i was writing back to file all the changes.
    2. Also i was checking if pc is online and if it is, closing the program inside constructor.
    3. But widget was not closing no matter what. So i assumed networkConfigurationManager->isOnline() function was not working. It seems widgets can not be closed when constructing.
    4. I was calling isOnline() before reading, causing writing nothing to the file before it is read.

    All these combined and caused this problem. Thank you for the help, i really appreciated it.


Log in to reply
 

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