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, portname 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 mode. The mode may either be a Fixnum or a String. If numeric, it should be one of the operating system specific constants (O_RDONLY, O_WRONLY, O_RDWR, O_APPEND and so on). See man open(2) for more information.
If the mode is given as a String, it must be one of the values listed in the following table.
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" | Binary file mode (may appear with
| any of the key letters listed above).
| Suppresses EOL <-> CRLF conversion on Windows. And
| sets external encoding to ASCII-8BIT unless explicitly
| specified.
-----+--------------------------------------------------------
"t" | Text file mode (may appear with
| any of the key letters listed above except "b").
The global constant ARGF (also accessible as $<) provides an IO-like
stream which allows access to all files mentioned on the command line (or
STDIN if no files are mentioned). ARGF provides the methods
#path and #filename to access the name of the
file currently being read.
Opens the file, optionally seeks to the given offset, then returns
length bytes (defaulting to the rest of the file).
read ensures the file is closed before returning. The open
mode would be “rb:ASCII-8BIT”.
IO.binread("testfile") #=> "This is line one\nThis is line two\nThis is line three\nAnd so on...\n" IO.binread("testfile", 20) #=> "This is line one\nThi" IO.binread("testfile", 20, 10) #=> "ne one\nThis is line "
static VALUE
rb_io_s_binread(int argc, VALUE *argv, VALUE io)
{
VALUE offset;
struct foreach_arg arg;
rb_scan_args(argc, argv, "12", NULL, NULL, &offset);
FilePathValue(argv[0]);
arg.io = rb_io_open(argv[0], rb_str_new_cstr("rb:ASCII-8BIT"), Qnil, Qnil);
if (NIL_P(arg.io)) return Qnil;
arg.argv = argv+1;
arg.argc = (argc > 1) ? 1 : 0;
if (!NIL_P(offset)) {
rb_io_seek(arg.io, offset, SEEK_SET);
}
return rb_ensure(io_s_read, (VALUE)&arg, rb_io_close, arg.io);
}
::copy_stream copies src to dst. src and dst is either a filename or an IO.
This method returns the number of bytes copied.
If optional arguments are not given, the start position of the copy is the beginning of the filename or the current file offset of the IO. The end position of the copy is the end of file.
If copy_length is given, No more than copy_length bytes are copied.
If src_offset is given, it specifies the start position of the copy.
When src_offset is specified and src is an IO, ::copy_stream doesn't move the current file offset.
static VALUE
rb_io_s_copy_stream(int argc, VALUE *argv, VALUE io)
{
VALUE src, dst, length, src_offset;
struct copy_stream_struct st;
MEMZERO(&st, struct copy_stream_struct, 1);
rb_scan_args(argc, argv, "22", &src, &dst, &length, &src_offset);
st.src = src;
st.dst = dst;
if (NIL_P(length))
st.copy_length = (off_t)-1;
else
st.copy_length = NUM2OFFT(length);
if (NIL_P(src_offset))
st.src_offset = (off_t)-1;
else
st.src_offset = NUM2OFFT(src_offset);
rb_ensure(copy_stream_body, (VALUE)&st, copy_stream_finalize, (VALUE)&st);
return OFFT2NUM(st.total);
}
Synonym for IO.new.
static VALUE
rb_io_s_for_fd(int argc, VALUE *argv, VALUE klass)
{
VALUE io = rb_obj_alloc(klass);
rb_io_initialize(argc, argv, io);
return io;
}
Executes the block for every line in the named I/O port, where lines are separated by sep.
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...
If the last argument is a hash, it's the keyword argument to open. See
IO.read for detail.
static VALUE
rb_io_s_foreach(int argc, VALUE *argv, VALUE self)
{
struct foreach_arg arg;
rb_scan_args(argc, argv, "13", NULL, NULL, NULL, NULL);
RETURN_ENUMERATOR(self, argc, argv);
open_key_args(argc, argv, &arg);
if (NIL_P(arg.io)) return Qnil;
return rb_ensure(io_s_foreach, (VALUE)&arg, rb_io_close, arg.io);
}
Returns a new IO object (a stream) for the given
IO object or integer file descriptor and mode string. See also
IO#fileno and IO.for_fd.
numeric file descriptor
file mode. a string or an integer
hash for specifiying mode by name.
When mode is an integer it must be combination of the modes
defined in File::Constants.
When mode is a string it must be in one of the following
forms:
“fmode”,
“fmode:extern”,
“fmode:extern:intern”.
extern is the external encoding name for the IO. intern is the internal encoding.
fmode must be combination of the directives. See the
description of class IO for a description of the directives.
opt can have the following keys
same as mode parameter
external encoding for the IO. “-” is a synonym for the default external encoding.
internal encoding for the IO. “-” is a synonym for the default internal encoding. If the value is nil no conversion occurs.
specifies external and internal encodings as “extern:intern”.
If the value is truth value, same as “b” in argument mode.
If the value is truth value, same as “t” in argument mode.
Also opt can have same keys in String#encode for
controlling conversion between the external encoding and the internal
encoding.
a = IO.new(2,"w") # '2' is standard error $stderr.puts "Hello" a.puts "World"
produces:
Hello World
io = IO.new(2, mode: 'w:UTF-16LE', cr_newline: true) io.puts "Hello, World!" io = IO.new(2, mode: 'w', cr_newline: true, external_encoding: Encoding::UTF_16LE) io.puts "Hello, World!"
both of aboves print “Hello, World!” in UTF-16LE to standard error output
with converting EOL generated by puts to CR.
static VALUE
rb_io_s_new(int argc, VALUE *argv, VALUE klass)
{
if (rb_block_given_p()) {
const char *cname = rb_class2name(klass);
rb_warn("%s::new() does not take block; use %s::open() instead",
cname, cname);
}
return rb_class_new_instance(argc, argv, klass);
}
With no associated block, open is a synonym for
IO.new. If the optional code block is given, it will be passed
io as an argument, and the IO object will
automatically be closed when the block terminates. In this instance,
IO.open returns the value of the block.
static VALUE
rb_io_s_open(int argc, VALUE *argv, VALUE klass)
{
VALUE io = rb_class_new_instance(argc, argv, klass);
if (rb_block_given_p()) {
return rb_ensure(rb_yield, io, io_close, io);
}
return io;
}
Creates a pair of pipe endpoints (connected to each other) and returns them
as a two-element array of IO objects: [
read_io, write_io ]. Not available on all
platforms.
If an encoding (encoding name or encoding object) is specified as an optional argument, read string from pipe is tagged with the encoding specified. If the argument is a colon separated two encoding names “A:B”, the read string is converted from encoding A (external encoding) to encoding B (internal encoding), then tagged with B. If two optional arguments are specified, those must be encoding objects or encoding names, and the first one is the external encoding, and the second one is the internal encoding. If the external encoding and the internal encoding is specified, optional hash argument specify the conversion option.
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>
static VALUE
rb_io_s_pipe(int argc, VALUE *argv, VALUE klass)
{
int pipes[2], state;
VALUE r, w, args[3], v1, v2;
VALUE opt;
rb_io_t *fptr, *fptr2;
int fmode = 0;
opt = pop_last_hash(&argc, argv);
rb_scan_args(argc, argv, "02", &v1, &v2);
if (rb_pipe(pipes) == -1)
rb_sys_fail(0);
args[0] = klass;
args[1] = INT2NUM(pipes[0]);
args[2] = INT2FIX(O_RDONLY);
r = rb_protect(io_new_instance, (VALUE)args, &state);
if (state) {
close(pipes[0]);
close(pipes[1]);
rb_jump_tag(state);
}
GetOpenFile(r, fptr);
io_encoding_set(fptr, v1, v2, opt);
args[1] = INT2NUM(pipes[1]);
args[2] = INT2FIX(O_WRONLY);
w = rb_protect(io_new_instance, (VALUE)args, &state);
if (state) {
close(pipes[1]);
if (!NIL_P(r)) rb_io_close(r);
rb_jump_tag(state);
}
GetOpenFile(w, fptr2);
rb_io_synchronized(fptr2);
extract_binmode(opt, &fmode);
fptr->mode |= fmode;
fptr2->mode |= fmode;
return rb_assoc_new(r, w);
}
Runs the specified command as a subprocess; the subprocess's standard
input and output will be connected to the returned IO object.
If cmd is a String “-'', then a
new instance of Ruby is started as the subprocess. If cmd is an
Array of String, then it will be used as the
subprocess's argv bypassing a shell. The array can
contains a hash at first for environments and a hash at last for options
similar to spawn. The default mode for the new file object is
“r'', but mode may be set to any of the modes listed in
the description for class IO. The last argument
opt qualifies