Results 1 to 12 of 12

Thread: read file from end to beginning..

  1. #1
    Join Date
    Jan 2006
    Location
    germany
    Posts
    75
    Thanks
    9
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default read file from end to beginning..

    its really a rather simple thing, i want to preview a textfile by showing its last 5 lines...
    is there an easy way i can read the last 5 lines from a file without parsing it entirely? or maybe even clearer: how can i find out how many lines the file has, how can i jump to certain line?

    thanks!
    Quote Originally Posted by Bertolt Brecht
    What is the robbing of a bank compared to the founding of a bank?

  2. #2
    Join Date
    Feb 2006
    Posts
    1
    Qt products
    Qt3
    Platforms
    Unix/X11 Windows

    Default Re: read file from end to beginning..

    In *nix systems there's the 'tail' command. Find out it's source code and explore it...

  3. #3
    Join Date
    Feb 2006
    Location
    Österreich
    Posts
    35
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: read file from end to beginning..

    Quote Originally Posted by soul_rebel
    its really a rather simple thing, i want to preview a textfile by showing its last 5 lines...
    is there an easy way i can read the last 5 lines from a file without parsing it entirely? or maybe even clearer: how can i find out how many lines the file has, how can i jump to certain line?

    thanks!
    I don't know if Qt has a similar function in its QFile class, but in raw file handling you could probably move the cursor of the file to the end with lseek(QFile::handle(), 0, SEEK_END).
    Then just keep using lseek and work backwards locating the newlines. Hold on, I'll just check the docs quickly. Yeah, QFile inherits one called seek() that does this. Just it in conjunction with QFile::size() to send the cursor to the end of the file. It's going to be a pain in the ass for you to scan those lines backwards though Have fun. If you really want to do it, I would guess the best bet would be to read the entire file into a string if it's not insanely large, then use
    Qt Code:
    1. int QString::lastIndexOf ( QChar ch, int from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive ) const
    To copy to clipboard, switch view to plain text mode 

    with '\n' as your QChar and an integer to hold the offset. Make a loop counting down from 4 to 0, and create a QStringList with the last 5 lines using filebuffer.at(offset+1). Remember, if you make the loop count upwards instead of downards, all your strings will be in reverse order.

    But no, you can't find out how many lines a file has without reading it. I mean, how else is it going to know how many newlines your file has if it can't scan the entire file and count them all for you? Counting the number of lines is no different from counting the number of times your file contains the letter 'a' or a comma. You can't magically tell without reading the entire file and doing some matching. Unless your text file is like 400000000000000000000000000000000 lines long or it has to be loaded a billion times sequentially, you'll save yourself about half an hour of unnecessary work by just doing it from front to back.
    Last edited by michel; 20th February 2006 at 13:20.
    My philosophy is: If you can use a free, open-source alternative: do it. And if you can't, pretend it's free and open-source and hope you don't get caught.

  4. #4
    Join Date
    Jan 2006
    Location
    germany
    Posts
    75
    Thanks
    9
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: read file from end to beginning..

    i know tail but it is rather complicated to understand undocumented unix code, also i do not want to invoke a pipe or fork a shell to execute the command....
    after all i just want to do simple file i/o !!
    Quote Originally Posted by Bertolt Brecht
    What is the robbing of a bank compared to the founding of a bank?

  5. #5
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: read file from end to beginning..

    A simple, but not the quickest solution is something like this:

    Qt Code:
    1. QString lines[5];
    2. int index = 0;
    3. QFile file("xxx");
    4. file.open(QIODevice::ReadOnly);
    5. while(!file.atEnd()){
    6. lines[index] = file.readLine();
    7. index = (index+1) %5
    8. }
    9. for(int i=0;i<5;i++) std::cout<< lines[index++ % 5];
    To copy to clipboard, switch view to plain text mode 

  6. #6
    Join Date
    Jan 2006
    Location
    germany
    Posts
    75
    Thanks
    9
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: read file from end to beginning..

    Quote Originally Posted by michel
    Yeah, QFile inherits one called seek()
    in qt3 it doesnt...

    but i could get the last position with size and move backwards with at() until i reach the 5th-last line and then simply readline...
    i'll try that now...

    @wysota: since your example parses the fil from the beginning, it could be rather slow in my app (the file could well be a couple of megs)
    Quote Originally Posted by Bertolt Brecht
    What is the robbing of a bank compared to the founding of a bank?

  7. #7
    Join Date
    Jan 2006
    Location
    germany
    Posts
    75
    Thanks
    9
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: read file from end to beginning..

    ok this does it:
    Qt Code:
    1. QString UpdateAvSrc::getLastLinesFromFile(QString pathToFile, int lines)
    2. {
    3. QFile file(pathToFile);
    4.  
    5. if (!file.exists())
    6. return "file doesn't exist...";
    7.  
    8. file.open(IO_ReadOnly);
    9.  
    10. file.at(file.size()-1);
    11.  
    12. int count = 0;
    13.  
    14. while ( (count <=lines) && (file.at() > 0) )
    15. {
    16. QChar ch = file.getch();
    17. file.at(file.at()-2); /// minus 2 because getch moves one forward
    18.  
    19. if (ch == '\n')
    20. count++;
    21.  
    22. }
    23.  
    24. QString r = file.readAll();
    25.  
    26. file.close();
    27.  
    28. return r;
    29. }
    To copy to clipboard, switch view to plain text mode 
    Quote Originally Posted by Bertolt Brecht
    What is the robbing of a bank compared to the founding of a bank?

  8. #8
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: read file from end to beginning..

    Quote Originally Posted by soul_rebel
    @wysota: since your example parses the fil from the beginning, it could be rather slow in my app (the file could well be a couple of megs)
    Yes, I know. I said it's simple, not that it's fastest. But reading char by char and making a seek every read is not efficient too. The fastest thing would be probably to make a kind of binary search -- split the file in half, take the second half, split it in half, take the second half, etc. until you have a single character. If it's a newline, mark the newline as found and go back one step, take the preceding character, check if it's newline, etc. If you do a smart check of each group, finding a n-th newline from the end of the file shouldn't be hard. Of course, in the worst case you have to scan the whole file...

  9. #9
    Join Date
    Jan 2006
    Location
    germany
    Posts
    75
    Thanks
    9
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: read file from end to beginning..

    if i only want the last three or five lines of a logfile that may have up to 40000 lines it is faster to read char by char from the end than continously splitting the thing in halves, is it not?
    thanks anyway!
    Quote Originally Posted by Bertolt Brecht
    What is the robbing of a bank compared to the founding of a bank?

  10. #10
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: read file from end to beginning..

    Quote Originally Posted by soul_rebel
    if i only want the last three or five lines of a logfile that may have up to 40000 lines it is faster to read char by char from the end than continously splitting the thing in halves, is it not?
    thanks anyway!
    Provided that you know that it contains 40000 lines, than yes. But what if it contains three or four (huge) lines?

    Besides, it is never worth reading char by char. Every device reads (at least) a complete block at once, so you can safely go 1024 by 1024 bytes at a time. It'll be much faster this way. And if you notice, that's like splitting the file in "halves" up to a 1k slice -- the algorithm is always the same, no matter if you start from beginning, end or from the middle. The whole idea is to have a way to check if a slice contains a new line without scanning each byte, to gain some computing time. If it doesn't, it's not worth checking it. For example on Windows you'd have to check only each second byte, as the newline consists of two characters. Another way would be to use 32b calculations to check whether a block may contain a newline.

    One way or the other, if you really value your time -- just cut&paste the code from "tail"

  11. #11
    Join Date
    Oct 2011
    Posts
    3
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: read file from end to beginning..

    mark it... I was confused by the question several days ago

  12. #12
    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: read file from end to beginning..

    Did you really need to wake up a six year old thread to add a nonsensical comment?

Similar Threads

  1. QFile can't read a file
    By Raccoon29 in forum Qt Programming
    Replies: 3
    Last Post: 11th February 2009, 20:24
  2. [Java] read and write a file
    By mickey in forum General Programming
    Replies: 3
    Last Post: 22nd June 2008, 10:43
  3. Replies: 1
    Last Post: 20th June 2008, 18:43
  4. qt-3.3.8 fail in scratchbox
    By nass in forum Installation and Deployment
    Replies: 0
    Last Post: 25th May 2007, 15:21
  5. Replies: 13
    Last Post: 1st June 2006, 14:01

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.