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

why QFile reads only new data?



  • I've created a simple .txt file, opened it successfully:

    if(!fileFlowTest->open(QIODevice::ReadOnly)) //tratata!
    

    Then i have a button, which have only one function:

    ui->labelFileUpd->setText(fileFlowTest->readAll());
    

    When i'm pressing the button first time, it shows correct text in the QLabel. When i press that again - QLabel becomes blank(like file is empty). But when i'm correcting data in textfile manually, and then save during runtime of my program, and then pressing the button, QLabel shows only new characters that i just typed in that file, instead of showing whole text existring in the file. Tried read/readline/readall, all gives same effect.

    And then i noticed, if i will not type additional letters in that file, but instead erase some, Qt will show some errors in the Application Output:

    QIODevice::read (QFile, "filepath"): Called with maxSize < 0

    What the problem is?

    P.S. opening and closing every time the file in button function works well, and i wanted to ask someone who knows. Is it bad to open() and close() QFile frequently? Like 10 times per second.



  • Found in documentation:

    You can get the current file position using pos(), or move to a new file position using seek().

    For reading file again, from the beginning, call Seek(0);



  • Found in documentation:

    You can get the current file position using pos(), or move to a new file position using seek().

    For reading file again, from the beginning, call Seek(0);



  • As you've seen from the docs, file access is sequential until you reset the file position pointer. so each sequential read just reads after the last file position that was read.



  • This is the general idea of how file handling works: It works the same in C as in C++ as in Qt. Your file handle has a pointer to the current position inside the file (possibly one for reading and a separate one for writing). Calling readAll() the first time sets the file pointer to a specific location. I would say it is pure luck that you are able to read anything at all after writing from another application. In general, the file handle would be in a specific state signalling end-of-file. Then, it does not make sense to read more data from the file.

    If you don't have a speed problem, I would advise to close the file each time (maybe even have a local QFile variable which closes automatically when destroyed). Keeping the file open – to me – is an optimization. (Don't optimize prematurely!) We have software which is not able to write to its file anymore while it is open by another application. Thus, you might run into trouble keeping the file open for so long.

    Depending on the size of the file you might reconsider reading the whole file each time. If this takes too long, you might reconsider optimizing it. Then, everything I said above does not apply. Since you have the file open anyway and might want to read only what is new, you could append it to the text already inside the label:

    ui->labelFileUpd->setText(ui->labelFileUpd->text() + fileFlowTest->readAll());  // untested if '+' works here
    

    This depends on your use case and the expected size of your files.



  • One more thing: On every OS except for Windows (as the others all are derived from Unix) keeping the file open would not neccesarilly work: One app has an open file handle while another tries to write to the file from the beginning, creating a new file under the old name. Then, both applications would see different versions of the same file. Once the first application closes its file handle the (already hidden file) will be deleted. This might be another reason to close the file handle every time.


Log in to reply