Method: IO#readpartial
- Defined in:
- io.c
#readpartial(maxlen) ⇒ String #readpartial(maxlen, out_string) ⇒ Object
Reads up to maxlen bytes from the stream; returns a string (either a new string or the given out_string). Its encoding is:
-
The unchanged encoding of
out_string, ifout_stringis given. -
ASCII-8BIT, otherwise.
-
Contains
maxlenbytes from the stream, if available. -
Otherwise contains all available bytes, if any available.
-
Otherwise is an empty string.
With the single non-negative integer argument maxlen given, returns a new string:
f = File.new('t.txt')
f.readpartial(20) # => "First line\nSecond l"
f.readpartial(20) # => "ine\n\nFourth line\n"
f.readpartial(20) # => "Fifth line\n"
f.readpartial(20) # Raises EOFError.
f.close
With both argument maxlen and string argument out_string given, returns modified out_string:
f = File.new('t.txt')
s = 'foo'
f.readpartial(20, s) # => "First line\nSecond l"
s = 'bar'
f.readpartial(0, s) # => ""
f.close
This method is useful for a stream such as a pipe, a socket, or a tty. It blocks only when no data is immediately available. This means that it blocks only when all of the following are true:
-
The byte buffer in the stream is empty.
-
The content of the stream is empty.
-
The stream is not at EOF.
When blocked, the method waits for either more data or EOF on the stream:
-
If more data is read, the method returns the data.
-
If EOF is reached, the method raises EOFError.
When not blocked, the method responds immediately:
-
Returns data from the buffer if there is any.
-
Otherwise returns data from the stream if there is any.
-
Otherwise raises EOFError if the stream has reached EOF.
Note that this method is similar to sysread. The differences are:
-
If the byte buffer is not empty, read from the byte buffer instead of “sysread for buffered IO (IOError)”.
-
It doesn’t cause Errno::EWOULDBLOCK and Errno::EINTR. When readpartial meets EWOULDBLOCK and EINTR by read system call, readpartial retries the system call.
The latter means that readpartial is non-blocking-flag insensitive. It blocks on the situation IO#sysread causes Errno::EWOULDBLOCK as if the fd is blocking mode.
Examples:
# # Returned Buffer Content Pipe Content
r, w = IO.pipe #
w << 'abc' # "" "abc".
r.readpartial(4096) # => "abc" "" ""
r.readpartial(4096) # (Blocks because buffer and pipe are empty.)
# # Returned Buffer Content Pipe Content
r, w = IO.pipe #
w << 'abc' # "" "abc"
w.close # "" "abc" EOF
r.readpartial(4096) # => "abc" "" EOF
r.readpartial(4096) # raises EOFError
# # Returned Buffer Content Pipe Content
r, w = IO.pipe #
w << "abc\ndef\n" # "" "abc\ndef\n"
r.gets # => "abc\n" "def\n" ""
w << "ghi\n" # "def\n" "ghi\n"
r.readpartial(4096) # => "def\n" "" "ghi\n"
r.readpartial(4096) # => "ghi\n" "" ""
3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 |
# File 'io.c', line 3618 static VALUE io_readpartial(int argc, VALUE *argv, VALUE io) { VALUE ret; ret = io_getpartial(argc, argv, io, Qnil, 0); if (NIL_P(ret)) rb_eof_error(); return ret; } |