Programming Ruby
The Pragmatic Programmer's Guide
class IO
Parent:
Object
Version:
1.6
Index:
foreach
new
pipe
popen
readlines
select
<<
binmode
clone
close
close_read
close_write
closed?
each
each_byte
each_line
eof
eof?
fcntl
fileno
flush
getc
gets
ioctl
isatty
lineno
lineno=
pid
pos
pos=
print
printf
putc
puts
read
readchar
readline
readlines
reopen
rewind
seek
stat
sync
sync=
sysread
syswrite
tell
to_i
to_io
tty?
ungetc
write
Subclasses: File
Class
IO is the basis for all input and output in Ruby.
An I/O stream may be
duplexed (that is, bidirectional), and so may use
more than one native operating system stream.
Many of the examples in this section use class
File, the only
standard subclass of
IO. The two classes are closely associated.
As used in this section,
aPortname may take any of the
following forms.
- A plain string represents a filename suitable for the
underlying operating system.
- A string starting with ``
|'' indicates a subprocess. The
remainder of the string following the ``|'' is invoked as a
process with appropriate input/output channels connected to it.
- A string equal to ``
|-'' will create another Ruby
instance as a subprocess.
Ruby will convert pathnames between different operating system
conventions if possible. For instance, on a Windows system the
filename ``
/gumby/ruby/test.rb'' will be opened as
``
\gumby\ruby\test.rb''. When specifying a
Windows-style filename in a Ruby string, remember to escape the
backslashes:
"c:\\gumby\\ruby\\test.rb"
Our examples here will use the Unix-style forward slashes;
File::SEPARATOR
can be used to get the platform-specific
separator character.
I/O ports may be opened in any one of several different modes, which are
shown in this section as
aModeString. This mode string must be one of the
values listed in Table 22.5 on page 326.
Mode strings
Mode
Meaning
``r''
Read-only, starts at beginning of file (default mode).
``r+''
Read-write, starts at beginning of file.
``w''
Write-only, truncates existing file
to zero length or creates a new file for writing.
``w+''
Read-write, truncates existing file to zero length
or creates a new file for reading and writing.
``a''
Write-only, starts at end of file if file exists,
otherwise creates a new file for writing.
``a+''
Read-write, starts at end of file if file exists,
otherwise creates a new file for reading and
writing.
``b''
(DOS/Windows only) Binary file mode (may appear with
any of the key letters listed above).
mixins
Enumerable:
collect, detect, each_with_index, entries, find, find_all, grep,
include?, map, max, member?, min, reject, select, sort, to_a
class methods
foreach
IO.foreach(
aPortName,
aSepString=
$/ )
{| line | block }
->
nil
Executes the block for every line in the
named I/O port, where lines are separated by
aSepString.
IO.foreach("testfile") {|x| print "GOT ", x }
produces:
GOT This is line one
GOT This is line two
GOT This is line three
GOT And so on...
new
IO.new(
anInteger,
aModeString )
->
aFile
Returns a new
File object (a stream) for the given
integer file descriptor and mode string. See also
IO#fileno
.
a = IO.new(2,"w") # '2' is standard error
$stderr.puts "Hello"
a.puts "World"
produces:
Creates a pair of pipe endpoints (connected to each other) and
returns them as a two-element array of
IO objects:
[
readFile,
writeFile ]. Not available on all
platforms.
In the example below, the two processes close the ends of the
pipe that they are not using. This is not just a cosmetic
nicety. The read end of a pipe will not generate an end of file
condition if there are any writers with the pipe still open. In
the case of the parent process, the
rd.read will never
return if it does not first issue a
wr.close.
rd, wr = IO.pipe
if fork
wr.close
puts "Parent got: <#{rd.read}>"
rd.close
Process.wait
else
rd.close
puts "Sending message to parent"
wr.write "Hi Dad"
wr.close
end
produces:
Sending message to parent
Parent got: <Hi Dad>
popen
IO.popen(
aCmdString,
aModeString="r" )
->
anIO
IO.popen(
aCmdString,
aModeString="r" )
{| anIO | block }
->
nil
Runs the specified command string as a subprocess; the
subprocess's standard input and output will be connected
to the returned
IO object. If
aCmdString starts with a
``
-'', then a new instance of Ruby is started as the subprocess.
The default mode for the new file object is ``r'', but
aModeString may be
set to any of the modes in Table 22.5 on page 326.
If a block is given, Ruby will run the command as a child
connected to Ruby with a pipe. Ruby's end of the pipe will be
passed as a parameter to the block.
If a block is given with a
aCmdString of ``
-'', the block
will be run in two separate processes: once in the parent, and
once in a child.
The parent process will be
passed the pipe object as a parameter to the block, the child
version of the block will be passed
nil, and the child's
standard in and standard out will be connected to the parent through the
pipe.
Not available on all platforms.
f = IO.popen("uname")
p f.readlines
puts "Parent is #{Process.pid}"
IO.popen ("date") { |f| puts f.gets }
IO.popen("-") {|f| $stderr.puts "#{Process.pid} is here, f is #{f}"}
produces:
["Linux\n"]
Parent is 561
Sun Jun 9 00:17:46 CDT 2002
564 is here, f is
561 is here, f is #<IO:0x401b54dc>
readlines
IO.readlines(
aPortName,
aSepString=
$/ )
->
anArray
Reads the entire file specified by
aPortName as individual
lines, and returns those lines in an array. Lines are
separated by
aSepString.
a = IO.readlines("testfile")
a[0]
サ
"This is line one\n"
select
IO.select(
readArray [,
writeArray
[
errorArray [
timeout
]
]
] )
->
anArray
or
nil
See
Kernel#select
on page 422.
instance methods
<<
ios <<
anObject
->
ios
String Output---Writes
anObject to
ios.
anObject will be
converted to a string using
to_s.
$stdout << "Hello " << "world!\n"
produces:
Puts
ios into binary mode. This is useful only in
MS-DOS/Windows environments. Once a stream is in binary mode, it cannot
be reset to nonbinary mode.
Creates a new I/O stream, copying all the attributes of
ios.
The file position is shared as well, so
reading from the clone will alter the file position of the
original, and vice-versa.
Closes
ios and flushes any pending writes to the
operating system.
The stream is unavailable for any further
data operations; an
IOError is raised if such an attempt is
made. I/O streams are automatically closed when they are claimed
by the garbage collector.
Closes the read end of a duplex I/O stream (i.e., one that
contains both a read and a write stream, such as a pipe).
Will raise an
IOError if the stream is not duplexed.
f = IO.popen("/bin/sh","r+")
f.close_read
f.readlines
produces:
prog.rb:3:in `readlines': not opened for reading (IOError)
from prog.rb:3
Closes the write end of a duplex I/O stream (i.e., one that
contains both a read and a write stream, such as a pipe).
Will raise an
IOError if the stream is not duplexed.
f = IO.popen("/bin/sh","r+")
f.close_write
f.print "nowhere"
produces:
prog.rb:3:in `write': not opened for writing (IOError)
from prog.rb:3:in `print'
from prog.rb:3
closed?
ios.closed?
->
true or
false
Returns
true if
ios is completely closed (for
duplex streams, both reader and writer),
false otherwise.
f = File.new("testfile")
f.close
サ
nil
f.closed?
サ
true
f = IO.popen("/bin/sh","r+")
f.close_write
サ
nil
f.closed?
サ
false
f.close_read
サ
nil
f.closed?
サ
true
each
ios.each(
aSepString=
$/ )
{| line | block }
->
ios
Executes the block for every line in
ios, where lines are
separated by
aSepString.
ios must be opened for reading or an
IOerror will be raised.
f = File.new("testfile")
f.each {|line| puts "#{f.lineno}: #{line}" }
produces:
1: This is line one
2: This is line two
3: This is line three
4: And so on...
each_byte
ios.each_byte {| byte | block }
->
nil
Calls the given block once for each byte (0..255) in
ios,
passing the byte as an argument.
The stream must be opened for reading or an
IOerror will be raised.
f = File.new("testfile")
checksum = 0
f.each_byte {|x| checksum ^= x }
サ
#<File:0x401b5cac>
checksum
サ
12
each_line
ios.each_line(
aSepString=
$/ ) {| line | block }
->
ios
Synonym for
IO#each
.
eof
ios.eof
->
true or
false
Returns true if
ios is at end of file. The
stream must be opened for reading or an
IOError will be
raised.
f = File.new("testfile")
dummy = f.readlines
f.eof
サ
true
eof?
ios.eof?
->
true or
false
Synonym for
IO#eof
.
fcntl
ios.fcntl(
anIntegerCmd,
anArg )
->
anInteger
Provides a mechanism for issuing low-level commands to control or
query file-oriented I/O streams.
Arguments and results are platform dependent.
If
anArg is a number, its value is passed directly. If it is
a string, it is interpreted as a binary sequence of bytes.
On Unix platforms, see
fcntl(2) for details.
Not implemented on all platforms.
Returns an integer representing the numeric file descriptor for
ios.
$stdin.fileno
サ
0
$stdout.fileno
サ
1
Flushes any buffered data within
ios to the underlying
operating system (note that this is Ruby internal buffering only; the
OS may buffer the data as well).
$stdout.print "no newline"
$stdout.flush
produces:
getc
ios.getc ->
aFixnum or
nil
Gets the next 8-bit byte (0..255) from
ios.
Returns
nil if called at end of file.
f = File.new("testfile")
f.getc
サ
84
f.getc
サ
104
gets
ios.gets(
aSepString=
$/ )
->
aString or
nil
Reads the next ``line'' from the I/O stream; lines are separated
by
aSepString. A separator of
nil reads the entire
contents, and a zero-length separator reads the input a paragraph
at a time (two successive newlines in the input separate
paragraphs). The stream must be opened for reading or an
IOerror will be raised. The line read in will be
returned and also assigned to
$_. Returns
nil if called at end of file.
File.new("testfile").gets
サ
"This is line one\n"
$_
サ
"This is line one\n"
ioctl
ios.ioctl(
anIntegerCmd,
anArg )
->
anInteger
Provides a mechanism for issuing low-level commands to control or
query I/O devices.
Arguments and results are platform dependent.
If
anArg is a number, its value is passed directly. If it is
a string, it is interpreted as a binary sequence of bytes.
On Unix platforms, see
ioctl(2) for details.
Not implemented on all platforms.
isatty
ios.isatty
->
true or
false
Returns
true if
ios is associated with a
terminal device (tty),
false otherwise.
File.new("testfile").isatty
サ
false
File.new("/dev/tty").isatty
サ
true
lineno
ios.lineno ->
anInteger
Returns the current line number in
ios. The stream
must be opened for reading.
lineno counts the number of
times
gets is called, rather than the number of
newlines encountered. The two values will differ if
gets
is called with a separator other than newline. See also the
$. variable.
f = File.new("testfile")
f.lineno
サ
0
f.gets
サ
"This is line one\n"
f.lineno
サ
1
f.gets
サ
"This is line two\n"
f.lineno
サ
2
lineno=
ios.lineno =
anInteger
->
anInteger
Manually sets the current line number to the given
value.
$. is updated only on the next read.
f = File.new("testfile")
f.gets
サ
"This is line one\n"
$.
サ
1
f.lineno = 1000
f.lineno
サ
1000
$. # lineno of last read
サ
1
f.gets
サ
"This is line two\n"
$. # lineno of last read
サ
1001
Returns the process ID of a child process associated with
ios. This will be set by
IO.popen
.
pipe = IO.popen("-")
if pipe
$stderr.puts "In parent, child pid is #{pipe.pid}"
else
$stderr.puts "In child, pid is #{$$}"
end
produces:
In parent, child pid is 600In child, pid is 600
Returns the current offset (in bytes) of
ios.
f = File.new("testfile")
f.pos
サ
0
f.gets
サ
"This is line one\n"
f.pos
サ
17
pos=
ios.pos =
anInteger
-> 0
Seeks to the given position (in bytes) in
ios.
f = File.new("testfile")
f.pos = 17
f.gets
サ
"This is line two\n"
print
ios.print(
[
anObject=
$_
]*
)
->
nil
Writes the given object(s) to
ios. The stream must be
opened for writing.
If the output record separator
(
$\)
is not
nil, it will be appended to the output. If
no arguments are given, prints
$_. Objects that aren't
strings will be converted by calling their
to_s method.
Returns
nil.
$stdout.print("This is ", 100, " percent.\n")
produces:
printf
ios.printf(
aFormatString
[,
anObject
]*
)
->
nil
Formats and writes to
ios, converting parameters under
control of the format string. See
Kernel#sprintf
on page 423 for details.
putc
ios.putc(
anObject )
->
anObject
Writes the given character (taken from a
String or a
Fixnum)
on
ios.
$stdout.putc "A"
$stdout.putc 65
produces:
puts
ios.puts(
[
anObject
]*
)
->
nil
Writes the given objects to
ios as with
IO#print
. Writes a record separator (typically a newline)
after any that do not already end with a newline sequence. If called with
an array argument, writes each element on a new line.
If called without arguments,
outputs a single record separator.
$stdout.puts("this", "is", "a", "test")
produces:
read
ios.read(
[
anInteger
] )
->
aString or
nil
Reads at most
anInteger bytes from the I/O stream, or to the
end of file if
anInteger is omitted.
Returns
nil if called at end of file.
f = File.new("testfile")
f.read(16)
サ
"This is line one"
Reads a character as with
IO#getc
, but raises an
EOFError
on end of file.
readline
ios.readline(
aSepString=
$/ )
->
aString
Reads a line as with
IO#gets
, but raises an
EOFError
on end of file.
readlines
ios.readlines(
aSepString=
$/ )
->
anArray
Reads all of the lines in
ios, and returns them in
anArray.
Lines are separated by the
optional
aSepString.
The stream must be opened for reading or an
IOerror will be raised.
f = File.new("testfile")
f.readlines[0]
サ
"This is line one\n"
reopen
ios.reopen(
anOtherIO ) ->
ios
ios.reopen(
aPath,
aModeStr ) ->
ios
Reassociates
ios with the I/O stream given in
anOtherIO or to a
new stream opened on
aPath. This may dynamically change
the actual class of this stream.
f1 = File.new("testfile")
f2 = File.new("testfile")
f2.readlines[0]
サ
"This is line one\n"
f2.reopen(f1)
サ
#<File:0x401b5a54>
f2.readlines[0]
サ
"This is line one\n"
Positions
ios to the beginning of input, resetting
lineno to zero.
f = File.new("testfile")
f.readline
サ
"This is line one\n"
f.rewind
サ
0
f.lineno
サ
0
f.readline
サ
"This is line one\n"
seek
ios.seek(
anInteger,
whence=
SEEK_SET )
-> 0
Seeks to a given offset
anInteger in the stream according
to the value of
whence:
IO::SEEK_END
Seeks to
anInteger plus end of stream (you probably
want a negative value for
anInteger).
IO::SEEK_SET
Seeks to the absolute location given by
anInteger.
f = File.new("testfile")
f.seek(-13, IO::SEEK_END)
サ
0
f.readline
サ
"And so on...\n"
Returns status information for
ios as an object of
type
File::Stat.
f = File.new("testfile")
s = f.stat
"%o" % s.mode
サ
"100644"
s.blksize
サ
4096
s.atime
サ
Sun Jun 09 00:17:48 CDT 2002
sync
ios.sync
->
true or
false
Returns the current ``sync mode'' of
ios. When sync
mode is true, all output is immediately flushed to the
underlying operating system and is not buffered by Ruby internally.
f = File.new("testfile")
f.sync
サ
false
sync=
ios.sync =
aBoolean
->
aBoolean
Sets the ``sync mode'' to
true or
false. When
sync mode is true, all output is immediately flushed to the
underlying operating system and is not buffered internally.
Returns the new state.
f = File.new("testfile")
f.sync = true
sysread
ios.sysread(
anInteger )
->
aString
Reads
anInteger bytes from
ios using a low-level
read and returns them as a string.
Do not mix with other methods that read from
ios
or you may get unpredictable results.
Raises
SystemCallError on error and
EOFError at end of
file.
f = File.new("testfile")
f.sysread(16)
サ
"This is line one"
syswrite
ios.syswrite(
aString )
->
anInteger
Writes the given string to
ios using a
low-level write.
Returns the number of bytes written.
Do not mix with other methods that write to
ios or you may get
unpredictable results.
Raises
SystemCallError on error.
f = File.new("out", "w")
f.syswrite("ABCDEF")
サ
6
tell
ios.tell ->
anInteger
Synonym for
IO#pos
.
to_i
ios.to_i ->
anInteger
Synonym for
IO#fileno
.
Returns
ios.
tty?
ios.tty?
->
true or
false
Synonym for
IO#isatty
.
ungetc
ios.ungetc(
anInteger )
->
nil
Pushes back one character onto
ios,
such that a subsequent buffered read will return it.
Only one character may be pushed back before a subsequent read
operation
(that is, you will
be able to read only the last of several characters that have
been pushed back). Has no effect with unbuffered reads (such as
IO#sysread
).
f = File.new("testfile")
サ
#<File:0x401b5b80>
c = f.getc
サ
84
f.ungetc(c)
サ
nil
f.getc
サ
84
write
ios.write(
aString )
->
anInteger
Writes the given string to
ios.
The stream must be opened for writing. If the
argument is not a string, it will be converted to a string using
to_s. Returns the number of bytes written.
count = $stdout.write( "This is a test\n" )
puts "That was #{count} bytes of data"
produces:
This is a test
That was 15 bytes of data
Extracted from the book "Programming Ruby -
The Pragmatic Programmer's Guide"
Copyright
©
2001 by Addison Wesley Longman, Inc. This material may
be distributed only subject to the terms and conditions set forth in
the Open Publication License, v1.0 or later (the latest version is
presently available at
http://www.opencontent.org/openpub/)).
Distribution of substantively modified versions of this document is
prohibited without the explicit permission of the copyright holder.
Distribution of the work or derivative of the work in any standard
(paper) book form is prohibited unless prior permission is obtained
from the copyright holder.