Adam Shelly
3/7/2008 5:59:00 PM
On 3/6/08, Pe=F1a, Botp <botp@delmonte-phil.com> wrote:
> On Behalf Of Tristin Davis:
> # But by the time you actually get count, isn't the line
> # already read in
> # memory. So if the line is 7 gigabytes, it'll probably crash
> # the system.
>
> read will accept arg on how many bytes to read.
>
> so how about,
>
...
> irb(main):043:0> File.open "test.rb" do |f| while x=3Df.read(2); p x; end=
; end
That solution essentially ignores linebreaks.
If you want to read up to a linebreak or N characters, whichever comes
first, you could one of these:
------
class IO
#read by characters
def for_eachA(linelen)
c=3D0
while (c)
buf=3D''
linelen.times {
break unless c=3Dgetc
buf<<c
break if c.chr=3D=3D $/
}
yield buf
end
end
#read by lines
def for_eachB(linelen)
re =3D Regexp.new(".*?#{Regexp.escape($/)}")
buf=3D''
while (line =3D read(linelen-buf.length))
buf =3D (buf+line).gsub(re){|l| yield l;''}
if buf.length =3D=3D linelen
yield buf
buf=3D''
end
end
yield buf
end
end
File.open("foreach.rb") do |f|
f.for_eachA(10){|l| p l}
end
File.open("foreach.rb") do |f|
f.for_eachB(10){|l| p l}
end
------
I'd guess the second version would be faster, but I didn't time it.
-Adam