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

How to rename a file while writing to file continuously?



  • However, QFile::rename() sometimes work, sometimes do not work, I even tried to close the QFile manually before rename and remove, but this do not fixed this issue either.

    I need to rename current file (log_filename_0 to log_filename_1 ) when file size exceeds and again i need to write into same file log_filename_0.


  • Moderators

    @Shankar-B

    QFile f1(log_filename_0);
    if(f1.open(QIODevice:: WriteOnly) {
    .....
    }
    f1.close();
    
    QFile::copy(log_filename_0, logfilename_1); // returns true if successful
    
    if(f1.open(QIODevice:: WriteOnly) {
    .....
    }
    
    
    
    


  • My requirement is when I have opened a file in an instance of my app. When I try to open the same file in another instance of the app I should know that the file is already opened. Since it is another instance which means another QFile object.
    I need to rename file in second instance only if file is closed in first instance.


  • Lifetime Qt Champion

    @Shankar-B This is not possible (neither with Qt nor with another low-level api afaik) - you have to think about another way to achieve this. Why do you want to open a file from two different instances?


  • Lifetime Qt Champion

    Hi,

    Are you thinking of something like logrotate ?



  • @SGaist yes



  • @Christian-Ehrlicher
    There are two application, first application will open file and write logs in to file.
    second application will monitor the file size which is opened by first application.
    if file size exceeds i need to rename the file from second application.

    How can i know in second application file is closed or not?


  • Lifetime Qt Champion

    @Shankar-B said in How to rename a file while writing to file continuously?:

    How can i know in second application file is closed or not?

    You can't but why needs the second app do the rename? Can't this be done by the first app? And what are you try to achieve?



  • @Shankar-B
    You cannot do what you want. Firstly, you cannot rename in second app what is currently open (via a file handle) in first app (likely OS limitation), and secondly even if you could how would first application know and start writing to a new log file?

    Even if file is closed in first app, it will lead to a (potential) race condition if you have second app renaming file at an instant where first file might be trying to add a new log to it.



  • @Christian-Ehrlicher
    My second application is logmanagement application. So renaming log files am doing it in my second application.
    my first application will write logs in file, while writing if file size exceeds i need to rename from second application.Size monitoring am doing in my second application.



  • @JonB
    Can we do this by file share.


  • Lifetime Qt Champion

    See my first post - it's not that easily possible. Do it from your first application as every other logger does.



  • @Shankar-B said in How to rename a file while writing to file continuously?:

    Can we do this by file share.

    Whether by "file share" (doesn't sound very Qt, platform-independent) or by locking, I think you will have implementation and/or race problems. The logging app would have to take & release exclusive access across each log action. The renaming app would have to take exclusive and then, while holding it, do rename, then release. This may not be allowed/work on OS, or it may be implemented non-atomically/robustly. Difficult to test reliably. Platform-specific, you'd have to read up. If tried from Qt, may well rely on what it uses for platform implementation, which is not documented/ to be relied on.

    It really isn't a good idea to try to do it this way.

    Also, if you mean literally

    while writing if file size exceeds i need to rename from second application

    you cannot go renaming a file right in the middle of writing to it.


  • Lifetime Qt Champion

    @Shankar-B what system are you targeting with that application ?



  • One major point is that the writing app needs to close the file and reopen it. On every OS you have a handle to a file, i.e. more or less a position on the disk. Directly after opening the name of the file is not important anymore for your file handle. Linux would (most likely) let you rename the file while it is open (at least removing works on open files). What would happen in this case is that entries in the file system would change, however the app would still point to the same place on the disk and continue writing on the file it has opened (the name is only to find the file, but it is not the file itself).

    So, in order to work correctly the writing app needs to have the logic: It needs to know when to change to a different file. Then it could be this app itself to rename the file. Close, rename, reopen. If you are writing to the same log file from multiple apps this approach does not work at all. The only way would be to open, then write, and immediatly close the file again. This, however, will be really slow.

    The best suggestion I have is that you extend your logmanager. Apps should be able to connect to the logmanager through a pipe. Each app then writes to its own pipe and the logmanager reads from the pipes and writes to the file. Then the logmanager can really manage the file.



  • @SimonSchroeder said in How to rename a file while writing to file continuously?:

    Linux would (most likely) let you rename the file while it is open (at least removing works on open files).

    True for Linux. But for Windows I think not. (It would be nice if OP stated which platform(s) are being targetted for a question like this.) E.g.
    https://docs.microsoft.com/en-us/windows/win32/fileio/moving-and-replacing-files

    Before a file can be copied, it must be closed or opened only for reading. No thread can have the file opened for writing.
    A file must also be closed before an application can move it.

    As for:

    The only way would be to open, then write, and immediatly close the file again.

    This may be required anyway, even if only one instance of OP's logging app. In order for the renaming governor app to "see" that the log file has grown it will need to use QFileSystemWatcher::fileChanged(). It may (well) be the case that this does not fire when data is being written on an open file handle until that file handle is closed. Certainly under Windows this would not surprise me, e.g. you tend to see file sizes being shown as 0 while being written to until writing is finished and they are closed. Not sure under Linux. Would have to test.


Log in to reply