I'm just wondering..
Let's say that we only need to read the last line. Can we do that without
reading the other lines?
Yes. Position your file pointer to the last byte in a file, read and
collect backwards each byte until you find a newline character (or the
first byte of the file). This is the last line.
You have to admit that this approach is rather inefficient.
Really?
I did a comparision of your code and my idea:
$ time ruby r.rb input
111111111111111111111111111111
999999999999999999999999999999
real 0m0.053s
user 0m0.000s
sys 0m0.004s
$ time ruby t.rb input
999999999999999999999999999999
real 0m0.043s
user 0m0.004s
sys 0m0.000s
the first result is your code, the second is mine.
Did you make sure that no OS disk buffering distorts this result? I suggest to include both variants in a single script, execute each variant multiple times in a loop and use Benchmark#bmbm.
I did the tests with a test file with almost 8,000,000 lines.
My q&d code:
f=File.open("input")
pos = 2
This opens the door for character loss of the last line under certain conditions.
f.seek(-pos, File::SEEK_END)
c = f.getc
result = ''
while c.chr != "\n"
result.insert(0,c.chr)
pos += 1
f.seek(-pos, File::SEEK_END)
c = f.getc
end
f.close
puts result
Also, this code is not equivalent to mine as it does not output the first line - which you can nicely see from the console output shown above.
Please keep also in mind, that my code tries to do some error checking which avoids printing the line from a single line file twice (although that bit is a slightly flawed, I'll leave that debugging task as exercise for the reader).
A final remark: using the block form of File.open is always safer.
Cheers
robert
···
On 21.12.2008 19:16, Thomas Preymesser wrote:
2008/12/21 Robert Klemme <shortcutter@googlemail.com>:
On 20.12.2008 17:46, Thomas Preymesser wrote:
2008/12/20 Yaser Sulaiman <yaserbuntu@gmail.com>:
--
remember.guy do |as, often| as.you_can - without end