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. Writing text file using QFile.

Writing text file using QFile.

Scheduled Pinned Locked Moved Solved General and Desktop
ubuntu 16.04writing txt filqfilefile.seek
13 Posts 5 Posters 10.0k 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.
  • V vishbynature
    22 Aug 2019, 11:03

    Hello,
    I want to write in a text file from a specific position say 80.
    what i have tried is this:
    QFile file("text.txt"); //global declaration

    file.open(QIODevice::WriteOnly | QIODevice::Text);
    QTextStream out(&file):

    file.seek(80);
    out << "Write from this location";

    but in my test.txt all the data gets erased or converted into line as follows
    @^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^Write from this location@^@^@^@^@^@^@^@^@^@^@^@

    what is this phenomenon called and how can i write to a text file from specific position as title intell.

    G Offline
    G Offline
    Gojir4
    wrote on 22 Aug 2019, 13:26 last edited by Gojir4
    #2

    @vishbynature Hi,

    Actually using QIODevice::WriteOnly will also "truncate" the file which means any previous content is erased.
    From the doc of QIODevice::WriteOnly:

    The device is open for writing. Note that, for file-system subclasses (e.g. QFile), this mode implies Truncate unless combined with ReadOnly, Append or NewOnly.

    So I guess you need to use

    file.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text);
    

    or some similar combination to make it working.

    V 1 Reply Last reply 22 Aug 2019, 13:41
    3
    • G Gojir4
      22 Aug 2019, 13:26

      @vishbynature Hi,

      Actually using QIODevice::WriteOnly will also "truncate" the file which means any previous content is erased.
      From the doc of QIODevice::WriteOnly:

      The device is open for writing. Note that, for file-system subclasses (e.g. QFile), this mode implies Truncate unless combined with ReadOnly, Append or NewOnly.

      So I guess you need to use

      file.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text);
      

      or some similar combination to make it working.

      V Offline
      V Offline
      vishbynature
      wrote on 22 Aug 2019, 13:41 last edited by
      #3

      @gojir4
      ok, I will try this.

      J G 2 Replies Last reply 22 Aug 2019, 13:58
      0
      • V vishbynature
        22 Aug 2019, 13:41

        @gojir4
        ok, I will try this.

        J Offline
        J Offline
        JonB
        wrote on 22 Aug 2019, 13:58 last edited by JonB
        #4

        @vishbynature
        I'm not sure QIODevice::Append is what you want. That will always append to your file (you can QFile.seek(), but as soon as you write it should ignore that and go to whatever the end is).

        You need to explain what is in the file (how big it is) at the instant you open it. For example, do you mean that if it is > 80 bytes long you want to start at 80? Would you then want it truncated as you start to write at 80, or would you want it to retain length but overwrite starting from 80? Or what?

        J 1 Reply Last reply 22 Aug 2019, 14:19
        1
        • V vishbynature
          22 Aug 2019, 13:41

          @gojir4
          ok, I will try this.

          G Offline
          G Offline
          Gojir4
          wrote on 22 Aug 2019, 14:11 last edited by
          #5

          @vishbynature @JonB is right about Append mode. I guess the easiest way to do this is to read the whole file, do the replacement and then write the whole file content.

          J 1 Reply Last reply 22 Aug 2019, 14:15
          0
          • G Gojir4
            22 Aug 2019, 14:11

            @vishbynature @JonB is right about Append mode. I guess the easiest way to do this is to read the whole file, do the replacement and then write the whole file content.

            J Offline
            J Offline
            JonB
            wrote on 22 Aug 2019, 14:15 last edited by
            #6

            @gojir4

            I guess the easiest way to do this is to read the whole file, do the replacement and then write the whole file content.

            Noooo! :) Or at least not necessarily. I just need to know what the OP actually wants! You can preserve what is there, and seek, by using QIODevice::ReadWrite instead of QIODevice::WriteOnly.

            1 Reply Last reply
            1
            • J JonB
              22 Aug 2019, 13:58

              @vishbynature
              I'm not sure QIODevice::Append is what you want. That will always append to your file (you can QFile.seek(), but as soon as you write it should ignore that and go to whatever the end is).

              You need to explain what is in the file (how big it is) at the instant you open it. For example, do you mean that if it is > 80 bytes long you want to start at 80? Would you then want it truncated as you start to write at 80, or would you want it to retain length but overwrite starting from 80? Or what?

              J Offline
              J Offline
              J.Hilk
              Moderators
              wrote on 22 Aug 2019, 14:19 last edited by
              #7

              @jonb said in Writing text file using QFile.:

              @vishbynature
              I'm not sure QIODevice::Append is what you want. That will always append to your file (you can QFile.seek(), but as soon as you write it should ignore that and go to whatever the end is).

              You need to explain what is in the file (how big it is) at the instant you open it. For example, do you mean that if it is > 80 bytes long you want to start at 80? Would you then want it truncated as you start to write at 80, or would you want it to retain length but overwrite starting from 80? Or what?

              are you sure? I haven't tested/checked it, but I assumed, Append was simply ReadWrite with a seek to the end of the file?


              Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


              Q: What's that?
              A: It's blue light.
              Q: What does it do?
              A: It turns blue.

              J 1 Reply Last reply 22 Aug 2019, 14:22
              0
              • J J.Hilk
                22 Aug 2019, 14:19

                @jonb said in Writing text file using QFile.:

                @vishbynature
                I'm not sure QIODevice::Append is what you want. That will always append to your file (you can QFile.seek(), but as soon as you write it should ignore that and go to whatever the end is).

                You need to explain what is in the file (how big it is) at the instant you open it. For example, do you mean that if it is > 80 bytes long you want to start at 80? Would you then want it truncated as you start to write at 80, or would you want it to retain length but overwrite starting from 80? Or what?

                are you sure? I haven't tested/checked it, but I assumed, Append was simply ReadWrite with a seek to the end of the file?

                J Offline
                J Offline
                JonB
                wrote on 22 Aug 2019, 14:22 last edited by JonB
                #8

                @j-hilk
                No, I never check :) But:

                QIODevice::Append 0x0004 The device is opened in append mode so that all data is written to the end of the file.

                That is standard for append in files. Any write auto-seeks to end of file before writing, not just at file open instant. It's how it works at C level etc. I think the OP will want QIODevice::ReadWrite.

                Having said that, I note it's a text file. A lot of people here think they can write stuff into the middle of a text file, and then the later stuff "squeezes down", or some such, which it will not. When we find out what they really want, it ends up being not an update to the file, but a read whole context while writing out new content as they go. That's why OP needs to clarify!

                J 1 Reply Last reply 22 Aug 2019, 14:27
                0
                • J JonB
                  22 Aug 2019, 14:22

                  @j-hilk
                  No, I never check :) But:

                  QIODevice::Append 0x0004 The device is opened in append mode so that all data is written to the end of the file.

                  That is standard for append in files. Any write auto-seeks to end of file before writing, not just at file open instant. It's how it works at C level etc. I think the OP will want QIODevice::ReadWrite.

                  Having said that, I note it's a text file. A lot of people here think they can write stuff into the middle of a text file, and then the later stuff "squeezes down", or some such, which it will not. When we find out what they really want, it ends up being not an update to the file, but a read whole context while writing out new content as they go. That's why OP needs to clarify!

                  J Offline
                  J Offline
                  J.Hilk
                  Moderators
                  wrote on 22 Aug 2019, 14:27 last edited by
                  #9

                  @jonb I checked, seems like my assumption was correct:

                  bool QFSFileEnginePrivate::openFh(QIODevice::OpenMode openMode, FILE *fh)
                  {
                      Q_ASSERT_X(openMode & QIODevice::Unbuffered, "QFSFileEngine::open",
                                 "QFSFileEngine no longer supports buffered mode; upper layer must buffer");
                      Q_Q(QFSFileEngine);
                      this->fh = fh;
                      fd = -1;
                      // Seek to the end when in Append mode.
                      if (openMode & QIODevice::Append) {
                          int ret;
                          do {
                              ret = QT_FSEEK(fh, 0, SEEK_END);
                          } while (ret != 0 && errno == EINTR);
                          if (ret != 0) {
                              q->setError(errno == EMFILE ? QFile::ResourceError : QFile::OpenError,
                                          QSystemError::stdString());
                              this->openMode = QIODevice::NotOpen;
                              this->fh = nullptr;
                              return false;
                          }
                      }
                      return true;
                  }
                  

                  Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                  Q: What's that?
                  A: It's blue light.
                  Q: What does it do?
                  A: It turns blue.

                  J 1 Reply Last reply 22 Aug 2019, 18:26
                  0
                  • V Offline
                    V Offline
                    vishbynature
                    wrote on 22 Aug 2019, 15:04 last edited by
                    #10

                    well that's a lot of information right now !!
                    what i am doing is I have stored information about monthly plan of my project in a text file. As soon as project runs i read all info from "test.txt" and display it on screen as per the month selected. About my UI it has a (cb)combobox which has names of months written and as the index of cb changes the info on lineEdits changes. everything ok uptil now. now for a particular month i want to modify the data thats why I wanted file.seek(80)
                    , here 80 is position of that data!! and my one month info is around 250 pos
                    so at max pos = 3000 for 12 months. I just want to edit data displayed and it should be modified in the right position!

                    P J 2 Replies Last reply 22 Aug 2019, 16:38
                    0
                    • V vishbynature
                      22 Aug 2019, 15:04

                      well that's a lot of information right now !!
                      what i am doing is I have stored information about monthly plan of my project in a text file. As soon as project runs i read all info from "test.txt" and display it on screen as per the month selected. About my UI it has a (cb)combobox which has names of months written and as the index of cb changes the info on lineEdits changes. everything ok uptil now. now for a particular month i want to modify the data thats why I wanted file.seek(80)
                      , here 80 is position of that data!! and my one month info is around 250 pos
                      so at max pos = 3000 for 12 months. I just want to edit data displayed and it should be modified in the right position!

                      P Offline
                      P Offline
                      Pablo J. Rogina
                      wrote on 22 Aug 2019, 16:38 last edited by
                      #11

                      @vishbynature said in Writing text file using QFile.:

                      I just want to edit data displayed and it should be modified in the right position!

                      would a database (just a simple one using SQLite) help you better with handling the storage/update of your data?

                      Upvote the answer(s) that helped you solve the issue
                      Use "Topic Tools" button to mark your post as Solved
                      Add screenshots via postimage.org
                      Don't ask support requests via chat/PM. Please use the forum so others can benefit from the solution in the future

                      1 Reply Last reply
                      1
                      • J J.Hilk
                        22 Aug 2019, 14:27

                        @jonb I checked, seems like my assumption was correct:

                        bool QFSFileEnginePrivate::openFh(QIODevice::OpenMode openMode, FILE *fh)
                        {
                            Q_ASSERT_X(openMode & QIODevice::Unbuffered, "QFSFileEngine::open",
                                       "QFSFileEngine no longer supports buffered mode; upper layer must buffer");
                            Q_Q(QFSFileEngine);
                            this->fh = fh;
                            fd = -1;
                            // Seek to the end when in Append mode.
                            if (openMode & QIODevice::Append) {
                                int ret;
                                do {
                                    ret = QT_FSEEK(fh, 0, SEEK_END);
                                } while (ret != 0 && errno == EINTR);
                                if (ret != 0) {
                                    q->setError(errno == EMFILE ? QFile::ResourceError : QFile::OpenError,
                                                QSystemError::stdString());
                                    this->openMode = QIODevice::NotOpen;
                                    this->fh = nullptr;
                                    return false;
                                }
                            }
                            return true;
                        }
                        
                        J Offline
                        J Offline
                        JonB
                        wrote on 22 Aug 2019, 18:26 last edited by JonB
                        #12

                        @j-hilk
                        Hi.

                        seems like my assumption was correct:

                        Sorry, but what assumption was correct? When the file is opened that code seeks to the end. Expected, but never at issue. But that's not all that opening in append mode does/should do. The question is: what happens when subsequently something writes to the file? If opened in append, it should (re-)seek (in case you've moved the write seek point) to end of file every time a write is performed.

                        This makes opening a file in append guarantee that access is "non-destructive" --- anything you write will always be at the end, so you cannot overwrite file content when opening for append. Suitable e.g. for a log file. Which would make the OP's attempt to write at byte #80 actually always write at the end if the file is longer than 80 bytes.

                        I'm not sure which are good examples to show you. I picked http://www.cplusplus.com/doc/oldtutorial/files/:

                        ios::app All output operations are performed at the end of the file, appending the content to the current content of the file. This flag can only be used in streams open for output-only operations.

                        Note the "All output operations are performed at the end of the file ...". Not just "initially the pointer is positioned at end of file". The Qt docs do say:

                        QIODevice::Append 0x0004 The device is opened in append mode so that all data is written to the end of the file.

                        1 Reply Last reply
                        1
                        • V vishbynature
                          22 Aug 2019, 15:04

                          well that's a lot of information right now !!
                          what i am doing is I have stored information about monthly plan of my project in a text file. As soon as project runs i read all info from "test.txt" and display it on screen as per the month selected. About my UI it has a (cb)combobox which has names of months written and as the index of cb changes the info on lineEdits changes. everything ok uptil now. now for a particular month i want to modify the data thats why I wanted file.seek(80)
                          , here 80 is position of that data!! and my one month info is around 250 pos
                          so at max pos = 3000 for 12 months. I just want to edit data displayed and it should be modified in the right position!

                          J Offline
                          J Offline
                          JonB
                          wrote on 22 Aug 2019, 18:39 last edited by JonB
                          #13

                          @vishbynature
                          I don't claim to understand what the best way to do whatever you want here is. Maybe @Pablo-J-Rogina's suggestion of a database. The one thing I can tell you is that achieving whatever you are attempting by seeking to byte #80 in a text file and overwriting what is there is not the right approach.

                          If you want some solution which involves sticking with text files, it should look something like: open the existing file for read, open a new file for write, read stuff from old and write to new, making whatever modifications you wish as you go along, close both, delete old file, rename new to old. A few more steps than you wanted! Or, if file not too large, read whole file into some memory structure, make your changes there, write whole memory structure back to the file, completely replacing it.

                          1 Reply Last reply
                          2

                          11/13

                          22 Aug 2019, 16:38

                          • Login

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