Results 1 to 4 of 4

Thread: Writing single line inside a text file

  1. #1
    Join Date
    Jun 2011
    Location
    Porto Alegre, Brazil
    Posts
    482
    Thanks
    165
    Thanked 2 Times in 2 Posts
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Writing single line inside a text file

    Hello!

    I would like to change a single line inside a QFile (.txt) file, not changing anything else on it.

    Now, as this (http://www.qtcentre.org/threads/4398...line-in-a-file) post tells, the easiest way of doing this is by using memory, and this is what I've implemented by now:

    Qt Code:
    1. QString textoFinal;
    2. MReadWrite *mrw = new MReadWrite(this);
    3.  
    4. if (mrw->openRead(filenameNotes))
    5. {
    6. textoFinal.reserve(mrw->size() + 8); //Tomorrow = 8
    7.  
    8. while (!mrw->isAtEnd())
    9. {
    10. const QString strTemp = mrw->readLine() + "\n";
    11.  
    12. if (!strTemp.contains(nota->getTitulo()))
    13. textoFinal.append(strTemp);
    14. else
    15. {
    16. if (toWhichTab == TAB_FORTOMORROW)
    17. textoFinal.append("0" + itemSeparator + "Tomorrow" + strTemp.section(itemSeparator,1));
    18. else //if (toWhichTab == TAB_TODAY)
    19. textoFinal.append("0" + itemSeparator + strTemp.section("Tomorrow",1));
    20. }
    21. }
    22.  
    23. textoFinal.squeeze();
    24.  
    25. mrw->closeFile();
    26. }
    27. else
    28. FILE_NOT_OPENING;
    29.  
    30. if (mrw->openWrite(filenameNotes,QFile::Truncate))
    31. {
    32. if (!mrw->write(textoFinal))
    33. BUG_OCCURANCE("changeNoteTodayForTomorrow/write");
    34.  
    35. mrw->closeFile();
    36. }
    37. else
    38. FILE_NOT_OPENING;
    39.  
    40. delete mrw;
    To copy to clipboard, switch view to plain text mode 

    Note: MReadWrite is a class used to quiclky and easier write and read from text files. It implements QFile and QTextStream.
    Note 2: it's irrelevant, but the code above is used to change a specific line in the code putting or taking out a "Tomorrow" string. "itemSeparator" is a default QString used to separate contents in the txt file.
    Note 3: Yes, I know, I could be using QStringList, but anyway... :P


    The problem, thought, is that this solution is quite bad when we are using huge text files. E.g., imagine I want to change the first line in a text file with 10.000 lines, each of them quite long. In that case, even with reserve/squeeze, the idea of huge memory comsumption in order to change one miserable single line seems quite inappropriate. Not to mention that reading from and writing to the hard disk is usually not understood as fast actions.

    So my question is: is there a way to change a single line in file without having to appeal to reading the entire file into memory, changing the desired line and writing it all back to the file?

    I already tried a solution such as:

    Qt Code:
    1. bool MReadWrite::writeLine(const QString text)
    2. {
    3. /*!
    4.   * \abstract This function is intended to write only a line
    5.   * inside the file, making all the rest of the
    6.   * file intact.
    7.   *
    8.   * \pre *goToLine already used
    9.   */
    10.  
    11. if (!isReading() || !isWriting())
    12. return false;
    13.  
    14. const qint64 currPosition = getPosition();
    15. const int lineSize = getLineExtension();
    16.  
    17. QString strBlanck;
    18.  
    19. if (lineSize > 5)
    20. strBlanck.reserve(lineSize);
    21.  
    22. for (int aaa = 0; aaa < lineSize; aaa++)
    23. strBlanck.append(" ");
    24.  
    25. if (!write(strBlanck))
    26. return false;
    27.  
    28. goToPosition(currPosition);
    29.  
    30. return write(text);
    31. }
    To copy to clipboard, switch view to plain text mode 

    But this function had quite an error. To explain, it opens the file as a ReadWrite mode, pick the current QTextStream position, write on it a fully blanck line, return to the original position and then write the intendend text. Now this function worked very well if the new string (const QString text) is shorter than the original one; but if is size is bigger, than it causes a error of "eating" the next line:

    Qt Code:
    1. //original text file data
    2. 1234567890
    3. 1234567890
    4. 1234567890
    5. 1234567890
    6.  
    7. //text file data with shorter new string
    8. XXXX
    9. 1234567890
    10. 1234567890
    11. 1234567890
    12.  
    13. //text file data with larger new string
    14. XXXXXXXXXXXX
    15. 34567890
    16. 1234567890
    17. 1234567890
    To copy to clipboard, switch view to plain text mode 

    And I have no idea about how to fix this.

    Glad for any help!!



    Obs.: btw, if you know a better way of creating a blanck QString without having to use a for with append(" "), I'ld be glad to know

  2. #2
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: Writing single line inside a text file

    You can only randomly update the file if the space already exists for the data you are inserting. If the file size needs to change (longer or shorter) then there is no way to avoid rewriting the entire file.

    if you know a better way of creating a blanck QString without having to use a for with append(" "), I'ld be glad to know
    Qt Code:
    1. QString blanks(80, ' ');
    2. QString hyphens(80, '-');
    To copy to clipboard, switch view to plain text mode 

  3. The following user says thank you to ChrisW67 for this useful post:

    Momergil (15th July 2013)

  4. #3
    Join Date
    Jun 2011
    Location
    Porto Alegre, Brazil
    Posts
    482
    Thanks
    165
    Thanked 2 Times in 2 Posts
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Writing single line inside a text file

    Quote Originally Posted by ChrisW67 View Post
    You can only randomly update the file if the space already exists for the data you are inserting. If the file size needs to change (longer or shorter) then there is no way to avoid rewriting the entire file.
    Sad :/ So this essentially means that if I open a .txt file say in Notepad.exe and that is a large file (10.000 lines or so) and goes there and edit one single line, making it bigger, than Notepad.exe actually rewrites the entire file? \o/ Same with a .docx file? (which I supposed would be treated in Qt with QTextDocument, which I imagine to be a little different from the treatment with QFile/QTextStream.)

    Thanks for the code!

  5. #4
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: Writing single line inside a text file

    Yes, entire files are rewritten when you update a sequential file. The Microsoft .docx file is a zipped XML file, i.e. effectively text, and operates the same way.

    By treating a text file as a random-access binary file you can perform some limited in-place updates of mid-file content but nothing that changes the size of the portion you are replacing. The Qt binary installer does something like this to update the various Qt install paths embedded in the Qt libraries: corelib/global/qconfig.cpp holds a preallocated, fixed-size buffer for each path and the installer writes the actual installed path into that space in the QtCore library binary file without rewriting the entire file.

  6. The following user says thank you to ChrisW67 for this useful post:

    Momergil (17th July 2013)

Similar Threads

  1. Start writing from a specific line in a file
    By nackasha in forum Newbie
    Replies: 1
    Last Post: 17th August 2011, 17:31
  2. writing in text file
    By ready in forum Qt Programming
    Replies: 3
    Last Post: 3rd July 2011, 22:20
  3. New line when writing a File
    By locke in forum Qt Programming
    Replies: 5
    Last Post: 17th May 2011, 11:27
  4. Writing the text within a text edit to a file
    By Splatify in forum Newbie
    Replies: 4
    Last Post: 23rd February 2011, 22:48
  5. writing to a text-file
    By QtBros61 in forum Newbie
    Replies: 7
    Last Post: 9th April 2010, 11:15

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.