End of Life Ruby 3.0 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 defined(RUBY_TEST_CRLF_ENVIRONMENT) || defined(_WIN32)
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 defined(RUBY_TEST_CRLF_ENVIRONMENT) || defined(_WIN32)
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 defined(RUBY_TEST_CRLF_ENVIRONMENT) || defined(_WIN32)
if (previous_mode == O_TEXT) {
setmode(fptr->fd, O_TEXT);
}
#endif
if (n == 0) return Qnil;
return str;
}
Reads length bytes from the I/O stream.
length must be a non-negative integer or nil.
If length is a positive integer, read tries to read length bytes without any conversion (binary mode). It returns nil if an EOF is encountered before anything can be read. Fewer than length bytes are returned if an EOF is encountered during the read. In the case of an integer length, the resulting string is always in ASCII-8BIT encoding.
If length is omitted or is nil, it reads until EOF and the encoding conversion is applied, if applicable. A string is returned even if EOF is encountered before any data is read.
If length is zero, it returns an empty string ("").
If the optional outbuf argument is present, it must reference a String, which will receive the data. The outbuf will contain only the received data after the method call even if it is not empty at the beginning.
When this method is called at end of file, it returns nil or "", depending on length: read, read(nil), and read(0) return "", read(<i>positive_integer</i>) returns nil.
f = File.new("testfile") f.read(16) #=> "This is line one" # read whole file open("file") do |f| data = f.read # This returns a string even if the file is empty. # ... end # iterate over fixed length records open("fixed-record-file") do |f| while record = f.read(256) # ... end end # iterate over variable length records, # each record is prefixed by its 32-bit length open("variable-record-file") do |f| while len = f.read(4) len = len.unpack("N")[0] # 32-bit length record = f.read(len) # This returns a string even if len is 0. end end
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 length (or until EOF). This behavior is preserved even if ios 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]
-