This is as inefficient as using File.foreach because it will read the whole file. I believe Ted was looking for a more efficient solution.
Ted, if you want to do this in Ruby and not resort to tail you can use IO#seek to seek to the end of the file and read backwards until you have read more than one line.
Kind regards
robert
···
On 07/22/2010 07:10 AM, Urabe Shyouhei wrote:
(2010/07/22 14:08), Urabe Shyouhei wrote:
Take a look at the doc for File.readline.
Oops... typo. I meant readlines. With it you can do something like
File.readlines(f).last
The second half on the Elif algorthim (see Elif::new). This method
returns the next line of the File, working from the end to the
beginning in reverse line order.
It works by moving the file pointer backwords MAX_READ_SIZE at a time,
storing seen lines in @line_buffer. Once the buffer contains at least
two lines (ensuring we have seen on full line) or the file pointer
reaches the head of the File, the last line from the buffer is
returned. When the buffer is exhausted, this will throw nil (from the
empty Array)."
Jesus.
···
On Thu, Jul 22, 2010 at 8:35 AM, Robert Klemme <shortcutter@googlemail.com> wrote:
On 07/22/2010 07:10 AM, Urabe Shyouhei wrote:
(2010/07/22 14:08), Urabe Shyouhei wrote:
Take a look at the doc for File.readline.
Oops... typo. I meant readlines. With it you can do something like
File.readlines(f).last
This is as inefficient as using File.foreach because it will read the whole
file. I believe Ted was looking for a more efficient solution.
Ted, if you want to do this in Ruby and not resort to tail you can use
IO#seek to seek to the end of the file and read backwards until you have
read more than one line.
Oops... typo. I meant readlines. With it you can do something like
File.readlines(f).last
This is as inefficient as using File.foreach because it will read the
whole file. I believe Ted was looking for a more efficient solution.
Ted, if you want to do this in Ruby and not resort to tail you can use
IO#seek to seek to the end of the file and read backwards until you have
read more than one line.
Kind regards
robert
Interesting, the problem is how to find how far back I need to go in the
seek (automatically of course)
f = File.new("testfile")
f.seek(-13, IO::SEEK_END) #=> 0
f.readline #=> "And so on...\n"
This still reads in the whole file plus you do not close the File
object properly. A solution that is efficient for large files will
use File#seek to move position to the end of the file and go backwards
from there.
This still reads in the whole file plus you do not close the File
object properly.
I'm sure you know how to do that properly.
A solution that is efficient for large files will
use File#seek to move position to the end of the file and go backwards
from there.
No, that can't work -- or that works only when you are sticking on the ASCII
character set. Multibyte encodings are not safe to read backwards
(sometimes). The only safe way is to read the whole content from the
beginning, at least one time.
Good point. Although pragmatically for fixed width and UTF-8 encoded files it will work and the performance gains for large files are significant enough to warrant this approach.
Cheers
robert
···
On 22.07.2010 16:22, Urabe Shyouhei wrote:
(2010/07/22 22:06), Robert Klemme wrote:
Then how about:
File.open(f).each_line.inject(nil){|x,y|y}
Slower than my first answer though.
A solution that is efficient for large files will
use File#seek to move position to the end of the file and go backwards
from there.
No, that can't work -- or that works only when you are sticking on the ASCII
character set. Multibyte encodings are not safe to read backwards
(sometimes). The only safe way is to read the whole content from the
beginning, at least one time.