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. Problems overwriting a text file with another with QFile
QtWS25 Last Chance

Problems overwriting a text file with another with QFile

Scheduled Pinned Locked Moved Solved General and Desktop
9 Posts 3 Posters 1.5k Views
  • 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.
  • A Offline
    A Offline
    AnUnusualRemote
    wrote on last edited by
    #1

    I've wrote a function that takes all lines from an existing file, changes a value by using a vector and then iterates through said vector to make a new text file. This text file is essentially the same as the first, but with a small change.
    Problem is that I need the new text file to be the same filename as the first (which obviously means just overwrite the file using the new one). I took this approach since writing the existing file into memory is beyond my ability, but I'm finding it hard to overwrite the file as of now. For some reason, even when I've closed the file using file.close(), I'm unable to overwrite the second file I've opened with the first file's filename. Code example is below.

    void Dashboard::borrowBook() {
        QFile bookFile("library/books.txt");
        std::vector<Book> BookVector;
        if(!bookFile.open(QIODevice::ReadWrite)){
            qCritical() << "Books cannot be found...";
            qCritical() << bookFile.errorString();
        }
        qInfo() << "Reading books from file...";
        bookFile.seek(0); // starts from absolute beginning of file //
        while(!bookFile.atEnd()){
             QString line = bookFile.readLine(); // reads line //
             Book Currentbook = line.split(","); // split text into categories //
             BookVector.push_back(Currentbook); // append to vector //
    
            }
            QString outputLine = ui->bookInfo->text();
            QStringList selectedBookTitle = outputLine.split(" -");
            for(Book& book: BookVector){
                if(selectedBookTitle[0] == book.title){
                    book.borrowed = "Yes";
                    qInfo() << book.borrowed;
                    break;
                }
            }
            QFile tempFile("library/booksTemp.txt");
            if(!tempFile.open(QIODevice::ReadWrite)){
                qCritical() << "BookTemp cannot be found...";
                qCritical() << bookFile.errorString();
            }
            QTextStream output(&tempFile);
            for (auto x: BookVector){
                output << x.title + "," + x.author + "," + x.desc + "," + x.borrowed + "," + x.cover;
            }
            tempFile.rename("library/books.txt");
            bookFile.close();
            tempFile.close();
        }
    

    Not sure where the error is here. I double checked and I can't see in this function where the bookFile could be left open, so I'm not sure why this isn't working. Any ideas?

    JonBJ M 2 Replies Last reply
    0
    • A AnUnusualRemote

      I've wrote a function that takes all lines from an existing file, changes a value by using a vector and then iterates through said vector to make a new text file. This text file is essentially the same as the first, but with a small change.
      Problem is that I need the new text file to be the same filename as the first (which obviously means just overwrite the file using the new one). I took this approach since writing the existing file into memory is beyond my ability, but I'm finding it hard to overwrite the file as of now. For some reason, even when I've closed the file using file.close(), I'm unable to overwrite the second file I've opened with the first file's filename. Code example is below.

      void Dashboard::borrowBook() {
          QFile bookFile("library/books.txt");
          std::vector<Book> BookVector;
          if(!bookFile.open(QIODevice::ReadWrite)){
              qCritical() << "Books cannot be found...";
              qCritical() << bookFile.errorString();
          }
          qInfo() << "Reading books from file...";
          bookFile.seek(0); // starts from absolute beginning of file //
          while(!bookFile.atEnd()){
               QString line = bookFile.readLine(); // reads line //
               Book Currentbook = line.split(","); // split text into categories //
               BookVector.push_back(Currentbook); // append to vector //
      
              }
              QString outputLine = ui->bookInfo->text();
              QStringList selectedBookTitle = outputLine.split(" -");
              for(Book& book: BookVector){
                  if(selectedBookTitle[0] == book.title){
                      book.borrowed = "Yes";
                      qInfo() << book.borrowed;
                      break;
                  }
              }
              QFile tempFile("library/booksTemp.txt");
              if(!tempFile.open(QIODevice::ReadWrite)){
                  qCritical() << "BookTemp cannot be found...";
                  qCritical() << bookFile.errorString();
              }
              QTextStream output(&tempFile);
              for (auto x: BookVector){
                  output << x.title + "," + x.author + "," + x.desc + "," + x.borrowed + "," + x.cover;
              }
              tempFile.rename("library/books.txt");
              bookFile.close();
              tempFile.close();
          }
      

      Not sure where the error is here. I double checked and I can't see in this function where the bookFile could be left open, so I'm not sure why this isn't working. Any ideas?

      JonBJ Offline
      JonBJ Offline
      JonB
      wrote on last edited by
      #2

      @AnUnusualRemote
      You should close() a QFile before attempting to rename() it, not afterwards.

      You should not open any files ReadWrite, you are not going to both read from and write to the same file.

      You have two possible ways of reading a file, changing it, and getting it written back to the original file:

      • Open it for read, read it all into memory, close it. Now open it for write, write out the changed data, close it.

      • Open file for read. Open new, temporary file for write. Read from file writing to temporary file, making changes as you go. Close both files. Rename the temporary file to original file finally.

      A 1 Reply Last reply
      1
      • A AnUnusualRemote

        I've wrote a function that takes all lines from an existing file, changes a value by using a vector and then iterates through said vector to make a new text file. This text file is essentially the same as the first, but with a small change.
        Problem is that I need the new text file to be the same filename as the first (which obviously means just overwrite the file using the new one). I took this approach since writing the existing file into memory is beyond my ability, but I'm finding it hard to overwrite the file as of now. For some reason, even when I've closed the file using file.close(), I'm unable to overwrite the second file I've opened with the first file's filename. Code example is below.

        void Dashboard::borrowBook() {
            QFile bookFile("library/books.txt");
            std::vector<Book> BookVector;
            if(!bookFile.open(QIODevice::ReadWrite)){
                qCritical() << "Books cannot be found...";
                qCritical() << bookFile.errorString();
            }
            qInfo() << "Reading books from file...";
            bookFile.seek(0); // starts from absolute beginning of file //
            while(!bookFile.atEnd()){
                 QString line = bookFile.readLine(); // reads line //
                 Book Currentbook = line.split(","); // split text into categories //
                 BookVector.push_back(Currentbook); // append to vector //
        
                }
                QString outputLine = ui->bookInfo->text();
                QStringList selectedBookTitle = outputLine.split(" -");
                for(Book& book: BookVector){
                    if(selectedBookTitle[0] == book.title){
                        book.borrowed = "Yes";
                        qInfo() << book.borrowed;
                        break;
                    }
                }
                QFile tempFile("library/booksTemp.txt");
                if(!tempFile.open(QIODevice::ReadWrite)){
                    qCritical() << "BookTemp cannot be found...";
                    qCritical() << bookFile.errorString();
                }
                QTextStream output(&tempFile);
                for (auto x: BookVector){
                    output << x.title + "," + x.author + "," + x.desc + "," + x.borrowed + "," + x.cover;
                }
                tempFile.rename("library/books.txt");
                bookFile.close();
                tempFile.close();
            }
        

        Not sure where the error is here. I double checked and I can't see in this function where the bookFile could be left open, so I'm not sure why this isn't working. Any ideas?

        M Offline
        M Offline
        mpergand
        wrote on last edited by
        #3

        @AnUnusualRemote said in Problems overwriting a text file with another with QFile:

        tempFile.rename("library/books.txt");

        check result with:
        if(!tempFile.rename("library/books.txt")) qDebug()<<tempFile.errorString();

        1 Reply Last reply
        0
        • JonBJ JonB

          @AnUnusualRemote
          You should close() a QFile before attempting to rename() it, not afterwards.

          You should not open any files ReadWrite, you are not going to both read from and write to the same file.

          You have two possible ways of reading a file, changing it, and getting it written back to the original file:

          • Open it for read, read it all into memory, close it. Now open it for write, write out the changed data, close it.

          • Open file for read. Open new, temporary file for write. Read from file writing to temporary file, making changes as you go. Close both files. Rename the temporary file to original file finally.

          A Offline
          A Offline
          AnUnusualRemote
          wrote on last edited by
          #4

          @JonB
          Renaming afterwards hasn't seem to have fixed the core issue. So I'm going to guess that this isn't the right way of overwriting a file?
          I'm not competent enough to read into memory (I am not familiar with working with memory at all), so the second way seems best. I'm already creating a new temporary file in this example with:

           QFile tempFile("library/booksTemp.txt");
          

          I've also made sure to change the temporary file to:

          if(!tempFile.open(QIODevice::WriteOnly)){
          

          As well as the original file:

          if(!bookFile.open(QIODevice::ReadOnly)){
          

          As for "Read from file writing to temporary file, making changes as you go", I'm not sure what you mean, isn't this what I'm doing in this example, with editing the vector which contains the original lines of the text file and then writing them in a new text file?
          The whole new code is down below.

          void Dashboard::borrowBook() {
              QFile bookFile("library/books.txt");
              std::vector<Book> BookVector;
              if(!bookFile.open(QIODevice::ReadOnly)){
                  qCritical() << "Books cannot be found...";
                  qCritical() << bookFile.errorString();
              }
              qInfo() << "Reading books from file...";
              bookFile.seek(0); // starts from absolute beginning of file //
              while(!bookFile.atEnd()){
                   QString line = bookFile.readLine(); // reads line //
                   Book Currentbook = line.split(","); // split text into categories //
                   BookVector.push_back(Currentbook); // append to vector //
          
                  }
                  QString outputLine = ui->bookInfo->text();
                  QStringList selectedBookTitle = outputLine.split(" -");
                  for(Book& book: BookVector){
                      if(selectedBookTitle[0] == book.title){
                          book.borrowed = "Yes";
                          qInfo() << book.borrowed;
                          break;
                      }
                  }
                  QFile tempFile("library/booksTemp.txt");
                  if(!tempFile.open(QIODevice::WriteOnly)){
                      qCritical() << "BookTemp cannot be found...";
                      qCritical() << bookFile.errorString();
                  }
                  QTextStream output(&tempFile);
                  for (auto x: BookVector){
                      output << x.title + "," + x.author + "," + x.desc + "," + x.borrowed + "," + x.cover;
                  }
                  bookFile.close();
                  tempFile.close();
                  tempFile.rename("library/books.txt");
              }
          

          @mpergand

          check result with:
          if(!tempFile.rename("library/books.txt")) qDebug()<<tempFile.errorString();

          It seems like the error string returns "Destination file exists". Meaning this seems to imply this isn't able to overwrite the original.

          M JonBJ 2 Replies Last reply
          0
          • A AnUnusualRemote

            @JonB
            Renaming afterwards hasn't seem to have fixed the core issue. So I'm going to guess that this isn't the right way of overwriting a file?
            I'm not competent enough to read into memory (I am not familiar with working with memory at all), so the second way seems best. I'm already creating a new temporary file in this example with:

             QFile tempFile("library/booksTemp.txt");
            

            I've also made sure to change the temporary file to:

            if(!tempFile.open(QIODevice::WriteOnly)){
            

            As well as the original file:

            if(!bookFile.open(QIODevice::ReadOnly)){
            

            As for "Read from file writing to temporary file, making changes as you go", I'm not sure what you mean, isn't this what I'm doing in this example, with editing the vector which contains the original lines of the text file and then writing them in a new text file?
            The whole new code is down below.

            void Dashboard::borrowBook() {
                QFile bookFile("library/books.txt");
                std::vector<Book> BookVector;
                if(!bookFile.open(QIODevice::ReadOnly)){
                    qCritical() << "Books cannot be found...";
                    qCritical() << bookFile.errorString();
                }
                qInfo() << "Reading books from file...";
                bookFile.seek(0); // starts from absolute beginning of file //
                while(!bookFile.atEnd()){
                     QString line = bookFile.readLine(); // reads line //
                     Book Currentbook = line.split(","); // split text into categories //
                     BookVector.push_back(Currentbook); // append to vector //
            
                    }
                    QString outputLine = ui->bookInfo->text();
                    QStringList selectedBookTitle = outputLine.split(" -");
                    for(Book& book: BookVector){
                        if(selectedBookTitle[0] == book.title){
                            book.borrowed = "Yes";
                            qInfo() << book.borrowed;
                            break;
                        }
                    }
                    QFile tempFile("library/booksTemp.txt");
                    if(!tempFile.open(QIODevice::WriteOnly)){
                        qCritical() << "BookTemp cannot be found...";
                        qCritical() << bookFile.errorString();
                    }
                    QTextStream output(&tempFile);
                    for (auto x: BookVector){
                        output << x.title + "," + x.author + "," + x.desc + "," + x.borrowed + "," + x.cover;
                    }
                    bookFile.close();
                    tempFile.close();
                    tempFile.rename("library/books.txt");
                }
            

            @mpergand

            check result with:
            if(!tempFile.rename("library/books.txt")) qDebug()<<tempFile.errorString();

            It seems like the error string returns "Destination file exists". Meaning this seems to imply this isn't able to overwrite the original.

            M Offline
            M Offline
            mpergand
            wrote on last edited by
            #5

            @AnUnusualRemote said in Problems overwriting a text file with another with QFile:

            It seems like the error string returns "Destination file exists". Meaning this seems to imply this isn't able to overwrite the original.

            That's the doc says:

            If a file with the name newName already exists, rename() returns false (i.e., QFile will not overwrite it).

            so you need to delete the original file first.

            A 1 Reply Last reply
            1
            • M mpergand

              @AnUnusualRemote said in Problems overwriting a text file with another with QFile:

              It seems like the error string returns "Destination file exists". Meaning this seems to imply this isn't able to overwrite the original.

              That's the doc says:

              If a file with the name newName already exists, rename() returns false (i.e., QFile will not overwrite it).

              so you need to delete the original file first.

              A Offline
              A Offline
              AnUnusualRemote
              wrote on last edited by
              #6

              @mpergand
              Perfect. That seemed to be my issue all along. Sorry, it was in the documentation and I must've missed it while browsing through. Thank you, same to @JonB.

              1 Reply Last reply
              0
              • A AnUnusualRemote

                @JonB
                Renaming afterwards hasn't seem to have fixed the core issue. So I'm going to guess that this isn't the right way of overwriting a file?
                I'm not competent enough to read into memory (I am not familiar with working with memory at all), so the second way seems best. I'm already creating a new temporary file in this example with:

                 QFile tempFile("library/booksTemp.txt");
                

                I've also made sure to change the temporary file to:

                if(!tempFile.open(QIODevice::WriteOnly)){
                

                As well as the original file:

                if(!bookFile.open(QIODevice::ReadOnly)){
                

                As for "Read from file writing to temporary file, making changes as you go", I'm not sure what you mean, isn't this what I'm doing in this example, with editing the vector which contains the original lines of the text file and then writing them in a new text file?
                The whole new code is down below.

                void Dashboard::borrowBook() {
                    QFile bookFile("library/books.txt");
                    std::vector<Book> BookVector;
                    if(!bookFile.open(QIODevice::ReadOnly)){
                        qCritical() << "Books cannot be found...";
                        qCritical() << bookFile.errorString();
                    }
                    qInfo() << "Reading books from file...";
                    bookFile.seek(0); // starts from absolute beginning of file //
                    while(!bookFile.atEnd()){
                         QString line = bookFile.readLine(); // reads line //
                         Book Currentbook = line.split(","); // split text into categories //
                         BookVector.push_back(Currentbook); // append to vector //
                
                        }
                        QString outputLine = ui->bookInfo->text();
                        QStringList selectedBookTitle = outputLine.split(" -");
                        for(Book& book: BookVector){
                            if(selectedBookTitle[0] == book.title){
                                book.borrowed = "Yes";
                                qInfo() << book.borrowed;
                                break;
                            }
                        }
                        QFile tempFile("library/booksTemp.txt");
                        if(!tempFile.open(QIODevice::WriteOnly)){
                            qCritical() << "BookTemp cannot be found...";
                            qCritical() << bookFile.errorString();
                        }
                        QTextStream output(&tempFile);
                        for (auto x: BookVector){
                            output << x.title + "," + x.author + "," + x.desc + "," + x.borrowed + "," + x.cover;
                        }
                        bookFile.close();
                        tempFile.close();
                        tempFile.rename("library/books.txt");
                    }
                

                @mpergand

                check result with:
                if(!tempFile.rename("library/books.txt")) qDebug()<<tempFile.errorString();

                It seems like the error string returns "Destination file exists". Meaning this seems to imply this isn't able to overwrite the original.

                JonBJ Offline
                JonBJ Offline
                JonB
                wrote on last edited by JonB
                #7

                @AnUnusualRemote
                You seem to have a lot of code/are making it all very complex.

                For everybody's benefit can you please take the time to make your indentation readable/sensible/consistent. Why are blocks of code indented under while(!bookFile.atEnd()){ if they are not inside the loop?

                I'm not competent enough to read into memory (I am not familiar with working with memory at all),

                For the record: you do appear to be reading the whole original content into memory. If I read the indentation right, you first read the whole file into BookVector. Then you write the whole content out from scratch. So you do not need the whole approach of QFile tempFile("library/booksTemp.txt");. You could simply first close QFile bookFile("library/books.txt"); from reading, re-open it for writing, and write BookVector to it. No temporary file, no renaming.

                A 1 Reply Last reply
                0
                • JonBJ JonB

                  @AnUnusualRemote
                  You seem to have a lot of code/are making it all very complex.

                  For everybody's benefit can you please take the time to make your indentation readable/sensible/consistent. Why are blocks of code indented under while(!bookFile.atEnd()){ if they are not inside the loop?

                  I'm not competent enough to read into memory (I am not familiar with working with memory at all),

                  For the record: you do appear to be reading the whole original content into memory. If I read the indentation right, you first read the whole file into BookVector. Then you write the whole content out from scratch. So you do not need the whole approach of QFile tempFile("library/booksTemp.txt");. You could simply first close QFile bookFile("library/books.txt"); from reading, re-open it for writing, and write BookVector to it. No temporary file, no renaming.

                  A Offline
                  A Offline
                  AnUnusualRemote
                  wrote on last edited by
                  #8

                  @JonB
                  Apologies, I've had trouble with indentation, I've never been good with it.
                  Yes, that's the idea. Each line is written into BookVector, which is a vector of the Book data type (a class that's just a QStringList consisting of 5 QStrings).
                  As I understand, wouldn't the problem be that I'm writing into the file, rather than over-writing? The impression I seem to get is that writing into a file that already exists does not delete anything in the original file.

                  JonBJ 1 Reply Last reply
                  0
                  • A AnUnusualRemote

                    @JonB
                    Apologies, I've had trouble with indentation, I've never been good with it.
                    Yes, that's the idea. Each line is written into BookVector, which is a vector of the Book data type (a class that's just a QStringList consisting of 5 QStrings).
                    As I understand, wouldn't the problem be that I'm writing into the file, rather than over-writing? The impression I seem to get is that writing into a file that already exists does not delete anything in the original file.

                    JonBJ Offline
                    JonBJ Offline
                    JonB
                    wrote on last edited by
                    #9

                    @AnUnusualRemote
                    Writing into a different file from whatever one you are reading from will indeed not interfere with the file you are reading. Do not attempt to write into the same file as you are reading from.

                    What you have now works for you, so that is fine.

                    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