End of Life Ruby 3.2 has reached end of life and gets no more fixes. Switch to Ruby 4.0 →
IO.read
static VALUE
rb_io_s_read(int argc, VALUE *argv, VALUE io)
{
VALUE opt, offset;
struct foreach_arg arg;
argc = rb_scan_args(argc, argv, "13:", NULL, NULL, &offset, NULL, &opt);
open_key_args(io, argc, argv, opt, &arg);
if (NIL_P(arg.io)) return Qnil;
if (!NIL_P(offset)) {
struct seek_arg sarg;
int state = 0;
sarg.io = arg.io;
sarg.offset = offset;
sarg.mode = SEEK_SET;
rb_protect(seek_before_access, (VALUE)&sarg, &state);
if (state) {
rb_io_close(arg.io);
rb_jump_tag(state);
}
if (arg.argc == 2) arg.argc = 1;
}
return rb_ensure(io_s_read, (VALUE)&arg, rb_io_close, arg.io);
}
Opens the stream, reads and returns some or all of its content, and closes the stream; returns nil if no bytes were read.
When called from class IO (but not subclasses of IO), this method has potential security vulnerabilities if called with untrusted input; see Command Injection.
The first argument must be a string; its meaning depends on whether it starts with the pipe character ('|'):
-
If so (and if
selfis IO), the rest of the string is a command to be executed as a subprocess. -
Otherwise, the string is the path to a file.
With only argument command given, executes the command in a shell, returns its entire $stdout:
IO.read('| cat t.txt') # => "First line\nSecond line\n\nThird line\nFourth line\n"
With only argument path given, reads in text mode and returns the entire content of the file at the given path:
IO.read('t.txt') # => "First line\nSecond line\n\nThird line\nFourth line\n"
On Windows, text mode can terminate reading and leave bytes in the file unread when encountering certain special bytes. Consider using IO.binread if all bytes in the file should be read.
For both forms, command and path, the remaining arguments are the same.
With argument length, returns length bytes if available:
IO.read('t.txt', 7) # => "First l" IO.read('t.txt', 700) # => "First line\r\nSecond line\r\n\r\nFourth line\r\nFifth line\r\n"
With arguments length and offset, returns length bytes if available, beginning at the given offset:
IO.read('t.txt', 10, 2) # => "rst line\nS" IO.read('t.txt', 10, 200) # => nil
Optional keyword arguments opts specify: