As well as using the usual loops to read data from an
IO
stream,
you can also use various Ruby iterators.
IO#each_byte
invokes a
block with the next 8-bit byte from the
IO
object (in this case,
an object of type
File
).
aFile = File.new("testfile")
aFile.each_byte {|ch| putc ch; putc ?. }
|
produces:
T.h.i.s. .i.s. .l.i.n.e. .o.n.e.
.T.h.i.s. .i.s. .l.i.n.e. .t.w.o.
.T.h.i.s. .i.s. .l.i.n.e. .t.h.r.e.e.
.A.n.d. .s.o. .o.n.......
.
|
IO#each_line
calls the block with the next line from the file.
In the next example, we'll make the original newlines visible using
String#dump
, so you can see that we're not cheating.
aFile.each_line {|line| puts "Got #{line.dump}" }
|
produces:
Got "This is line one\n"
Got "This is line two\n"
Got "This is line three\n"
Got "And so on...\n"
|
You can pass
each_line
any sequence of characters as a line
separator, and it will break up the input accordingly, returning
the line ending at the end of each line of data. That's why you see
the ``
\n
'' characters in the output of the previous example.
In the next example, we'll use ``
e
'' as the line separator.
aFile.each_line("e") do |line|
puts "Got #{ line.dump }"
end
|
produces:
Got "This is line"
Got " one"
Got "\nThis is line"
Got " two\nThis is line"
Got " thre"
Got "e"
Got "\nAnd so on...\n"
|
If you combine the idea of an iterator with the auto-closing block
feature, you get
IO.foreach
. This method takes the name of an
I/O source, opens it for reading, calls the iterator once for every
line in the file, and then closes the file automatically.
IO.foreach("testfile") { |line| puts line }
|
produces:
This is line one
This is line two
This is line three
And so on...
|
Or, if you prefer, you can retrieve an entire file into an array of
lines:
arr = IO.readlines("testfile")
|
arr.length
|
� |
4
|
arr[0]
|
� |
"This is line one\n"
|
Don't forget that I/O is never certain in an uncertain
world---exceptions will be raised on most errors, and you should be
ready to catch them and take appropriate action.