From: Jesús Gabriel y Galán on 22 Jul 2010 03:45 On Thu, Jul 22, 2010 at 8:35 AM, Robert Klemme <shortcutter(a)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. I think this is the algorithm used by James Gray in Elif: http://elif.rubyforge.org/ From those docs: " gets(sep_string = $/) 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.
From: Urabe Shyouhei on 22 Jul 2010 03:58 (2010/07/22 15:35), Robert Klemme 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. Then how about: File.open(f).each_line.inject(nil){|x,y|y} Slower than my first answer though.
From: Robert Klemme on 22 Jul 2010 09:06 2010/7/22 Urabe Shyouhei <shyouhei(a)ruby-lang.org>: > (2010/07/22 15:35), Robert Klemme 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. > > Then how about: > > File.open(f).each_line.inject(nil){|x,y|y} > > Slower than my first answer though. 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. Cheers robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/
From: Ted Flethuseo on 22 Jul 2010 10:08 Robert Klemme 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. > > 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" Ted. -- Posted via http://www.ruby-forum.com/.
From: Urabe Shyouhei on 22 Jul 2010 10:22 (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. > > 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.
First
|
Prev
|
Next
|
Last
Pages: 1 2 3 Prev: Enumerators and generators Next: functions to escape and unescape strings in rails |