End of Life Ruby 3.1 has reached end of life and gets no more fixes. Switch to Ruby 4.0 →
IO#read
static VALUE
io_read(int argc, VALUE *argv, VALUE io)
{
rb_io_t *fptr;
long n, len;
VALUE length, str;
int shrinkable;
#if RUBY_CRLF_ENVIRONMENT
int previous_mode;
#endif
rb_scan_args(argc, argv, "02", &length, &str);
if (NIL_P(length)) {
GetOpenFile(io, fptr);
rb_io_check_char_readable(fptr);
return read_all(fptr, remain_size(fptr), str);
}
len = NUM2LONG(length);
if (len < 0) {
rb_raise(rb_eArgError, "negative length %ld given", len);
}
shrinkable = io_setstrbuf(&str,len);
GetOpenFile(io, fptr);
rb_io_check_byte_readable(fptr);
if (len == 0) {
io_set_read_length(str, 0, shrinkable);
return str;
}
READ_CHECK(fptr);
#if RUBY_CRLF_ENVIRONMENT
previous_mode = set_binary_mode_with_seek_cur(fptr);
#endif
n = io_fread(str, 0, len, fptr);
io_set_read_length(str, n, shrinkable);
#if RUBY_CRLF_ENVIRONMENT
if (previous_mode == O_TEXT) {
setmode(fptr->fd, O_TEXT);
}
#endif
if (n == 0) return Qnil;
return str;
}
Reads bytes from the stream (in binary mode):
-
If
maxlenisnil, reads all bytes. -
Otherwise reads
maxlenbytes, if available. -
Otherwise reads all bytes.
Returns a string (either a new string or the given out_string) containing the bytes read. The encoding of the string depends on both maxLen and out_string:
-
maxlenisnil: uses internal encoding ofself(regardless of whetherout_stringwas given). -
maxlennotnil:-
out_stringgiven: encoding ofout_stringnot modified. -
out_stringnot given: ASCII-8BIT is used.
-
Without Argument out_string
When argument out_string is omitted, the returned value is a new string:
f = File.new('t.txt') f.read # => "This is line one.\nThis is the second line.\nThis is the third line.\n" f.rewind f.read(40) # => "This is line one.\r\nThis is the second li" f.read(40) # => "ne.\r\nThis is the third line.\r\n" f.read(40) # => nil
If maxlen is zero, returns an empty string.
With Argument out_string
When argument out_string is given, the returned value is out_string, whose content is replaced:
f = File.new('t.txt') s = 'foo' # => "foo" f.read(nil, s) # => "This is line one.\nThis is the second line.\nThis is the third line.\n" s # => "This is line one.\nThis is the second line.\nThis is the third line.\n" f.rewind s = 'bar' f.read(40, s) # => "This is line one.\r\nThis is the second li" s # => "This is line one.\r\nThis is the second li" s = 'baz' f.read(40, s) # => "ne.\r\nThis is the third line.\r\n" s # => "ne.\r\nThis is the third line.\r\n" s = 'bat' f.read(40, s) # => nil s # => ""
Note that this method behaves like the fread() function in C. This means it retries to invoke read(2) system calls to read data with the specified maxlen (or until EOF).
This behavior is preserved even if the stream is in non-blocking mode. (This method is non-blocking-flag insensitive as other methods.)
If you need the behavior like a single read(2) system call, consider readpartial, read_nonblock, and sysread.
Ruby version changes
-
3.0
-
IO#wait_readable,IO#wait_writable,IO#read,IO#writeand other related methods (e.g.IO#puts,IO#gets) may invoke the scheduler hook io_wait(io, events, timeout) in a non-blocking execution context. [Feature #16786]
-