Class: IO
Overview
An instance of class IO (commonly called a stream) represents an input/output stream in the underlying operating system. Class IO is the basis for input and output in Ruby.
Class File is the only class in the Ruby core that is a subclass of IO. Some classes in the Ruby standard library are also subclasses of IO; these include TCPSocket and UDPSocket.
The global constant ARGF (also accessible as $<
) provides an IO-like stream that allows access to all file paths found in ARGV (or found in STDIN if ARGV is empty). ARGF is not itself a subclass of IO.
Class StringIO provides an IO-like stream that handles a String. StringIO is not itself a subclass of IO.
Important objects based on IO include:
-
$stdin.
-
$stdout.
-
$stderr.
-
Instances of class File.
An instance of IO may be created using:
-
IO.new: returns a new IO object for the given integer file descriptor.
-
IO.open: passes a new IO object to the given block.
-
IO.popen: returns a new IO object that is connected to the $stdin and $stdout of a newly-launched subprocess.
-
Kernel#open: Returns a new IO object connected to a given source: stream, file, or subprocess.
Like a File stream, an IO stream has:
-
A read/write mode, which may be read-only, write-only, or read/write; see Read/Write Mode.
-
A data mode, which may be text-only or binary; see Data Mode.
-
Internal and external encodings; see Encodings.
And like other IO streams, it has:
-
A position, which determines where in the stream the next read or write is to occur; see Position.
-
A line number, which is a special, line-oriented, “position” (different from the position mentioned above); see Line Number.
Extension io/console
Extension io/console
provides numerous methods for interacting with the console; requiring it adds numerous methods to class IO.
Example Files
Many examples here use these variables:
:include: doc/examples/files.rdoc
Open Options
A number of IO methods accept optional keyword arguments that determine how a new stream is to be opened:
-
:mode
: Stream mode. -
:flags
: Integer file open flags; Ifmode
is also given, the two are bitwise-ORed. -
:external_encoding
: External encoding for the stream. -
:internal_encoding
: Internal encoding for the stream.'-'
is a synonym for the default internal encoding. If the value isnil
no conversion occurs. -
:encoding
: Specifies external and internal encodings as'extern:intern'
. -
:textmode
: If a truthy value, specifies the mode as text-only, binary otherwise. -
:binmode
: If a truthy value, specifies the mode as binary, text-only otherwise. -
:autoclose
: If a truthy value, specifies that thefd
will close when the stream closes; otherwise it remains open. -
:path:
If a string value is provided, it is used in #inspect and is available as #path method.
Also available are the options offered in String#encode, which may control conversion between external and internal encoding.
Basic IO
You can perform basic stream IO with these methods, which typically operate on multi-byte strings:
-
IO#read: Reads and returns some or all of the remaining bytes from the stream.
-
IO#write: Writes zero or more strings to the stream; each given object that is not already a string is converted via
to_s
.
Position
An IO stream has a nonnegative integer position, which is the byte offset at which the next read or write is to occur. A new stream has position zero (and line number zero); method rewind
resets the position (and line number) to zero.
The relevant methods:
-
IO#tell (aliased as
#pos
): Returns the current position (in bytes) in the stream. -
IO#pos=: Sets the position of the stream to a given integer
new_position
(in bytes). -
IO#seek: Sets the position of the stream to a given integer
offset
(in bytes), relative to a given positionwhence
(indicating the beginning, end, or current position). -
IO#rewind: Positions the stream at the beginning (also resetting the line number).
Open and Closed Streams
A new IO stream may be open for reading, open for writing, or both.
A stream is automatically closed when claimed by the garbage collector.
Attempted reading or writing on a closed stream raises an exception.
The relevant methods:
-
IO#close: Closes the stream for both reading and writing.
-
IO#close_read: Closes the stream for reading.
-
IO#close_write: Closes the stream for writing.
-
IO#closed?: Returns whether the stream is closed.
End-of-Stream
You can query whether a stream is positioned at its end:
-
IO#eof? (also aliased as
#eof
): Returns whether the stream is at end-of-stream.
You can reposition to end-of-stream by using method IO#seek:
f = File.new('t.txt')
f.eof? # => false
f.seek(0, :END)
f.eof? # => true
f.close
Or by reading all stream content (which is slower than using IO#seek):
f.rewind
f.eof? # => false
f.read # => "First line\nSecond line\n\nFourth line\nFifth line\n"
f.eof? # => true
Line IO
You can read an IO stream line-by-line using these methods:
-
IO#each_line: Reads each remaining line, passing it to the given block.
-
IO#gets: Returns the next line.
-
IO#readline: Like #gets, but raises an exception at end-of-stream.
-
IO#readlines: Returns all remaining lines in an array.
Each of these reader methods accepts:
-
An optional line separator,
sep
; see Line Separator. -
An optional line-size limit,
limit
; see Line Limit.
For each of these reader methods, reading may begin mid-line, depending on the stream’s position; see Position:
f = File.new('t.txt')
f.pos = 27
f.each_line {|line| p line }
f.close
Output:
"rth line\n"
"Fifth line\n"
You can write to an IO stream line-by-line using this method:
-
IO#puts: Writes objects to the stream.
Line Separator
Each of these methods uses a line separator, which is the string that delimits lines:
-
IO.foreach.
-
IO.readlines.
-
IO#each_line.
-
IO#gets.
-
IO#readline.
-
IO#readlines.
The default line separator is the given by the global variable $/
, whose value is by default "\n"
. The line to be read next is all data from the current position to the next line separator:
f = File.new('t.txt')
f.gets # => "First line\n"
f.gets # => "Second line\n"
f.gets # => "\n"
f.gets # => "Fourth line\n"
f.gets # => "Fifth line\n"
f.close
You can specify a different line separator:
f = File.new('t.txt')
f.gets('l') # => "First l"
f.gets('li') # => "ine\nSecond li"
f.gets('lin') # => "ne\n\nFourth lin"
f.gets # => "e\n"
f.close
There are two special line separators:
-
nil
: The entire stream is read into a single string:f = File.new('t.txt') f.gets(nil) # => "First line\nSecond line\n\nFourth line\nFifth line\n" f.close
-
''
(the empty string): The next “paragraph” is read (paragraphs being separated by two consecutive line separators):f = File.new('t.txt') f.gets('') # => "First line\nSecond line\n\n" f.gets('') # => "Fourth line\nFifth line\n" f.close
Line Limit
Each of these methods uses a line limit, which specifies that the number of bytes returned may not be (much) longer than the given limit
;
-
IO.foreach.
-
IO.readlines.
-
IO#each_line.
-
IO#gets.
-
IO#readline.
-
IO#readlines.
A multi-byte character will not be split, and so a line may be slightly longer than the given limit.
If limit
is not given, the line is determined only by sep
.
# Text with 1-byte characters.
File.open('t.txt') {|f| f.gets(1) } # => "F"
File.open('t.txt') {|f| f.gets(2) } # => "Fi"
File.open('t.txt') {|f| f.gets(3) } # => "Fir"
File.open('t.txt') {|f| f.gets(4) } # => "Firs"
# No more than one line.
File.open('t.txt') {|f| f.gets(10) } # => "First line"
File.open('t.txt') {|f| f.gets(11) } # => "First line\n"
File.open('t.txt') {|f| f.gets(12) } # => "First line\n"
# Text with 2-byte characters, which will not be split.
File.open('t.rus') {|f| f.gets(1).size } # => 1
File.open('t.rus') {|f| f.gets(2).size } # => 1
File.open('t.rus') {|f| f.gets(3).size } # => 2
File.open('t.rus') {|f| f.gets(4).size } # => 2
Line Separator and Line Limit
With arguments sep
and limit
given, combines the two behaviors:
-
Returns the next line as determined by line separator
sep
. -
But returns no more bytes than are allowed by the limit.
Example:
File.open('t.txt') {|f| f.gets('li', 20) } # => "First li"
File.open('t.txt') {|f| f.gets('li', 2) } # => "Fi"
Line Number
A readable IO stream has a non-negative integer line number.
The relevant methods:
-
IO#lineno: Returns the line number.
-
IO#lineno=: Resets and returns the line number.
Unless modified by a call to method IO#lineno=, the line number is the number of lines read by certain line-oriented methods, according to the given line separator sep
:
-
IO.foreach: Increments the line number on each call to the block.
-
IO#each_line: Increments the line number on each call to the block.
-
IO#gets: Increments the line number.
-
IO#readline: Increments the line number.
-
IO#readlines: Increments the line number for each line read.
A new stream is initially has line number zero (and position zero); method rewind
resets the line number (and position) to zero:
f = File.new('t.txt')
f.lineno # => 0
f.gets # => "First line\n"
f.lineno # => 1
f.rewind
f.lineno # => 0
f.close
Reading lines from a stream usually changes its line number:
f = File.new('t.txt', 'r')
f.lineno # => 0
f.readline # => "This is line one.\n"
f.lineno # => 1
f.readline # => "This is the second line.\n"
f.lineno # => 2
f.readline # => "Here's the third line.\n"
f.lineno # => 3
f.eof? # => true
f.close
Iterating over lines in a stream usually changes its line number:
File.open('t.txt') do |f|
f.each_line do |line|
p "position=#{f.pos} eof?=#{f.eof?} lineno=#{f.lineno}"
end
end
Output:
"position=11 eof?=false lineno=1"
"position=23 eof?=false lineno=2"
"position=24 eof?=false lineno=3"
"position=36 eof?=false lineno=4"
"position=47 eof?=true lineno=5"
Unlike the stream’s position, the line number does not affect where the next read or write will occur:
f = File.new('t.txt')
f.lineno = 1000
f.lineno # => 1000
f.gets # => "First line\n"
f.lineno # => 1001
f.close
Associated with the line number is the global variable $.
:
-
When a stream is opened,
$.
is not set; its value is left over from previous activity in the process:$. = 41 f = File.new('t.txt') $. = 41 # => 41 f.close
-
When a stream is read,
$.
is set to the line number for that stream:f0 = File.new('t.txt') f1 = File.new('t.dat') f0.readlines # => ["First line\n", "Second line\n", "\n", "Fourth line\n", "Fifth line\n"] $. # => 5 f1.readlines # => ["\xFE\xFF\x99\x90\x99\x91\x99\x92\x99\x93\x99\x94"] $. # => 1 f0.close f1.close
-
Methods IO#rewind and IO#seek do not affect
$.
:f = File.new('t.txt') f.readlines # => ["First line\n", "Second line\n", "\n", "Fourth line\n", "Fifth line\n"] $. # => 5 f.rewind f.seek(0, :SET) $. # => 5 f.close
Character IO
You can process an IO stream character-by-character using these methods:
-
IO#getc: Reads and returns the next character from the stream.
-
IO#readchar: Like #getc, but raises an exception at end-of-stream.
-
IO#ungetc: Pushes back (“unshifts”) a character or integer onto the stream.
-
IO#putc: Writes a character to the stream.
-
IO#each_char: Reads each remaining character in the stream, passing the character to the given block.
Byte IO
You can process an IO stream byte-by-byte using these methods:
-
IO#getbyte: Returns the next 8-bit byte as an integer in range 0..255.
-
IO#readbyte: Like #getbyte, but raises an exception if at end-of-stream.
-
IO#ungetbyte: Pushes back (“unshifts”) a byte back onto the stream.
-
IO#each_byte: Reads each remaining byte in the stream, passing the byte to the given block.
Codepoint IO
You can process an IO stream codepoint-by-codepoint:
-
IO#each_codepoint: Reads each remaining codepoint, passing it to the given block.
What’s Here
First, what’s elsewhere. Class IO:
-
Inherits from class Object.
-
Includes module Enumerable, which provides dozens of additional methods.
Here, class IO provides methods that are useful for:
Creating
-
::new (aliased as ::for_fd): Creates and returns a new IO object for the given integer file descriptor.
-
::open: Creates a new IO object.
-
::pipe: Creates a connected pair of reader and writer IO objects.
-
::popen: Creates an IO object to interact with a subprocess.
-
::select: Selects which given IO instances are ready for reading, writing, or have pending exceptions.
Reading
-
::binread: Returns a binary string with all or a subset of bytes from the given file.
-
::read: Returns a string with all or a subset of bytes from the given file.
-
::readlines: Returns an array of strings, which are the lines from the given file.
-
#getbyte: Returns the next 8-bit byte read from
self
as an integer. -
#getc: Returns the next character read from
self
as a string. -
#gets: Returns the line read from
self
. -
#pread: Returns all or the next n bytes read from
self
, not updating the receiver’s offset. -
#read: Returns all remaining or the next n bytes read from
self
for a given n. -
#read_nonblock: the next n bytes read from
self
for a given n, in non-block mode. -
#readbyte: Returns the next byte read from
self
; same as #getbyte, but raises an exception on end-of-stream. -
#readchar: Returns the next character read from
self
; same as #getc, but raises an exception on end-of-stream. -
#readline: Returns the next line read from
self
; same as #getline, but raises an exception of end-of-stream. -
#readlines: Returns an array of all lines read read from
self
. -
#readpartial: Returns up to the given number of bytes from
self
.
Writing
-
::binwrite: Writes the given string to the file at the given filepath, in binary mode.
-
::write: Writes the given string to
self
. -
#<<: Appends the given string to
self
. -
#print: Prints last read line or given objects to
self
. -
#printf: Writes to
self
based on the given format string and objects. -
#putc: Writes a character to
self
. -
#puts: Writes lines to
self
, making sure line ends with a newline. -
#pwrite: Writes the given string at the given offset, not updating the receiver’s offset.
-
#write: Writes one or more given strings to
self
. -
#write_nonblock: Writes one or more given strings to
self
in non-blocking mode.
Positioning
-
#lineno: Returns the current line number in
self
. -
#lineno=: Sets the line number is
self
. -
#pos (aliased as #tell): Returns the current byte offset in
self
. -
#pos=: Sets the byte offset in
self
. -
#reopen: Reassociates
self
with a new or existing IO stream. -
#rewind: Positions
self
to the beginning of input. -
#seek: Sets the offset for
self
relative to given position.
Iterating
-
::foreach: Yields each line of given file to the block.
-
#each (aliased as #each_line): Calls the given block with each successive line in
self
. -
#each_byte: Calls the given block with each successive byte in
self
as an integer. -
#each_char: Calls the given block with each successive character in
self
as a string. -
#each_codepoint: Calls the given block with each successive codepoint in
self
as an integer.
Settings
-
#autoclose=: Sets whether
self
auto-closes. -
#binmode: Sets
self
to binary mode. -
#close: Closes
self
. -
#close_on_exec=: Sets the close-on-exec flag.
-
#close_read: Closes
self
for reading. -
#close_write: Closes
self
for writing. -
#set_encoding: Sets the encoding for
self
. -
#set_encoding_by_bom: Sets the encoding for
self
, based on its Unicode byte-order-mark. -
#sync=: Sets the sync-mode to the given value.
Querying
-
#autoclose?: Returns whether
self
auto-closes. -
#binmode?: Returns whether
self
is in binary mode. -
#close_on_exec?: Returns the close-on-exec flag for
self
. -
#closed?: Returns whether
self
is closed. -
#eof? (aliased as #eof): Returns whether
self
is at end-of-stream. -
#external_encoding: Returns the external encoding object for
self
. -
#fileno (aliased as #to_i): Returns the integer file descriptor for
self
-
#internal_encoding: Returns the internal encoding object for
self
. -
#pid: Returns the process ID of a child process associated with
self
, ifself
was created by ::popen. -
#stat: Returns the File::Stat object containing status information for
self
. -
#sync: Returns whether
self
is in sync-mode. -
#tty? (aliased as #isatty): Returns whether
self
is a terminal.
Buffering
-
#fdatasync: Immediately writes all buffered data in
self
to disk. -
#flush: Flushes any buffered data within
self
to the underlying operating system. -
#fsync: Immediately writes all buffered data and attributes in
self
to disk. -
#ungetbyte: Prepends buffer for
self
with given integer byte or string. -
#ungetc: Prepends buffer for
self
with given string.
Low-Level Access
-
::sysopen: Opens the file given by its path, returning the integer file descriptor.
-
#advise: Announces the intention to access data from
self
in a specific way. -
#fcntl: Passes a low-level command to the file specified by the given file descriptor.
-
#ioctl: Passes a low-level command to the device specified by the given file descriptor.
-
#sysread: Returns up to the next n bytes read from self using a low-level read.
-
#sysseek: Sets the offset for
self
. -
#syswrite: Writes the given string to
self
using a low-level write.
Other
-
::copy_stream: Copies data from a source to a destination, each of which is a filepath or an IO-like object.
-
::try_convert: Returns a new IO object resulting from converting the given object.
-
#inspect: Returns the string representation of
self
.
Direct Known Subclasses
Defined Under Namespace
Modules: WaitReadable, WaitWritable Classes: Buffer, EAGAINWaitReadable, EAGAINWaitWritable, EINPROGRESSWaitReadable, EINPROGRESSWaitWritable, EWOULDBLOCKWaitReadable, EWOULDBLOCKWaitWritable, TimeoutError
Constant Summary collapse
- READABLE =
Readable event mask for IO#wait.
INT2NUM(RUBY_IO_READABLE)
- WRITABLE =
Writable event mask for IO#wait.
INT2NUM(RUBY_IO_WRITABLE)
- PRIORITY =
Priority event mask for IO#wait.
INT2NUM(RUBY_IO_PRIORITY)
- SEEK_SET =
Set I/O position from the beginning
INT2FIX(SEEK_SET)
- SEEK_CUR =
Set I/O position from the current position
INT2FIX(SEEK_CUR)
- SEEK_END =
Set I/O position from the end
INT2FIX(SEEK_END)
- SEEK_DATA =
Set I/O position to the next location containing data
INT2FIX(SEEK_DATA)
- SEEK_HOLE =
Set I/O position to the next hole
INT2FIX(SEEK_HOLE)
Constants included from File::Constants
File::Constants::APPEND, File::Constants::BINARY, File::Constants::CREAT, File::Constants::DIRECT, File::Constants::DSYNC, File::Constants::EXCL, File::Constants::LOCK_EX, File::Constants::LOCK_NB, File::Constants::LOCK_SH, File::Constants::LOCK_UN, File::Constants::NOATIME, File::Constants::NOCTTY, File::Constants::NOFOLLOW, File::Constants::NONBLOCK, File::Constants::NULL, File::Constants::RDONLY, File::Constants::RDWR, File::Constants::RSYNC, File::Constants::SHARE_DELETE, File::Constants::SYNC, File::Constants::TMPFILE, File::Constants::TRUNC, File::Constants::WRONLY
Class Method Summary collapse
-
.binread(path, length = nil, offset = 0) ⇒ String?
Behaves like IO.read, except that the stream is opened in binary mode with ASCII-8BIT encoding.
-
.binwrite(path, string, offset = 0) ⇒ Integer
Behaves like IO.write, except that the stream is opened in binary mode with ASCII-8BIT encoding.
-
.copy_stream(src, dst, src_length = nil, src_offset = 0) ⇒ Integer
Copies from the given
src
to the givendst
, returning the number of bytes copied. -
.for_fd(fd, mode = 'r', **opts) ⇒ IO
Synonym for IO.new.
-
.foreach(*args) ⇒ Object
Calls the block with each successive line read from the stream.
-
.new(*args) ⇒ Object
:nodoc:.
-
.open(*args) ⇒ Object
call-seq: IO.open(fd, mode = ‘r’, **opts) -> io IO.open(fd, mode = ‘r’, **opts) {|io| … } -> object.
-
.pipe(*args) ⇒ Object
Creates a pair of pipe endpoints,
read_io
andwrite_io
, connected to each other. -
.popen(*args) ⇒ Object
Executes the given command
cmd
as a subprocess whose $stdin and $stdout are connected to a new streamio
. -
.read(path, length = nil, offset = 0, **opts) ⇒ String?
Opens the stream, reads and returns some or all of its content, and closes the stream; returns
nil
if no bytes were read. -
.readlines(*args) ⇒ Object
Returns an array of all lines read from the stream.
-
.select(read_ios, write_ios = [], error_ios = [], timeout = nil) ⇒ Array?
Invokes system call select(2), which monitors multiple file descriptors, waiting until one or more of the file descriptors becomes ready for some class of I/O operation.
-
.sysopen(path, mode = 'r', perm = 0666) ⇒ Integer
Opens the file at the given path with the given mode and permissions; returns the integer file descriptor.
-
.try_convert(object) ⇒ nil
Attempts to convert
object
into an IO object via methodto_io
; returns the new IO object if successful, ornil
otherwise:. -
.write(path, data, offset = 0, **opts) ⇒ Integer
Opens the stream, writes the given
data
to it, and closes the stream; returns the number of bytes written.
Instance Method Summary collapse
-
#<<(object) ⇒ self
Writes the given
object
toself
, which must be opened for writing (see Access Modes); returnsself
; ifobject
is not a string, it is converted via methodto_s
:. -
#advise(advice, offset = 0, len = 0) ⇒ nil
Invokes Posix system call posix_fadvise(2), which announces an intention to access data from the current file in a particular manner.
-
#autoclose=(bool) ⇒ Boolean
Sets auto-close flag.
-
#autoclose? ⇒ Boolean
Returns
true
if the underlying file descriptor of ios will be closed at its finalization or at calling #close, otherwisefalse
. -
#binmode ⇒ self
Sets the stream’s data mode as binary (see Data Mode).
-
#binmode? ⇒ Boolean
Returns
true
if the stream is on binary mode,false
otherwise. -
#close ⇒ nil
Closes the stream for both reading and writing if open for either or both; returns
nil
. -
#close_on_exec=(bool) ⇒ Boolean
Sets a close-on-exec flag.
-
#close_on_exec? ⇒ Boolean
Returns
true
if the stream will be closed on exec,false
otherwise:. -
#close_read ⇒ nil
Closes the stream for reading if open for reading; returns
nil
. -
#close_write ⇒ nil
Closes the stream for writing if open for writing; returns
nil
. -
#closed? ⇒ Boolean
Returns
true
if the stream is closed for both reading and writing,false
otherwise. -
#each(*args) ⇒ Object
Calls the block with each remaining line read from the stream; returns
self
. -
#each_byte ⇒ Object
Calls the given block with each byte (0..255) in the stream; returns
self
. -
#each_char ⇒ Object
Calls the given block with each character in the stream; returns
self
. -
#each_codepoint ⇒ Object
Calls the given block with each codepoint in the stream; returns
self
:. -
#each_line(*args) ⇒ Object
Calls the block with each remaining line read from the stream; returns
self
. -
#eof ⇒ Boolean
Returns
true
if the stream is positioned at its end,false
otherwise; see Position:. -
#eof ⇒ Boolean
Returns
true
if the stream is positioned at its end,false
otherwise; see Position:. -
#external_encoding ⇒ Encoding?
Returns the Encoding object that represents the encoding of the stream, or
nil
if the stream is in write mode and no encoding is specified. -
#fcntl(integer_cmd, argument) ⇒ Integer
Invokes Posix system call fcntl(2), which provides a mechanism for issuing low-level commands to control or query a file-oriented I/O stream.
-
#fdatasync ⇒ 0
Immediately writes to disk all data buffered in the stream, via the operating system’s:
fdatasync(2)
, if supported, otherwise viafsync(2)
, if supported; otherwise raises an exception. -
#fileno ⇒ Integer
(also: #to_i)
Returns the integer file descriptor for the stream:.
-
#flush ⇒ self
Flushes data buffered in
self
to the operating system (but does not necessarily flush data buffered in the operating system):. -
#fsync ⇒ 0
Immediately writes to disk all data buffered in the stream, via the operating system’s
fsync(2)
. -
#getbyte ⇒ Integer?
Reads and returns the next byte (in range 0..255) from the stream; returns
nil
if already at end-of-stream. -
#getc ⇒ nil
Reads and returns the next 1-character string from the stream; returns
nil
if already at end-of-stream. -
#gets(*args) ⇒ Object
Reads and returns a line from the stream; assigns the return value to
$_
. -
#new(fd, mode = 'r', **opts) ⇒ IO
constructor
Creates and returns a new IO object (file stream) from a file descriptor.
-
#initialize_copy(io) ⇒ Object
:nodoc:.
-
#inspect ⇒ String
Returns a string representation of
self
:. -
#internal_encoding ⇒ Encoding?
Returns the Encoding object that represents the encoding of the internal string, if conversion is specified, or
nil
otherwise. -
#ioctl(integer_cmd, argument) ⇒ Integer
Invokes Posix system call ioctl(2), which issues a low-level command to an I/O device.
-
#isatty ⇒ Boolean
Returns
true
if the stream is associated with a terminal device (tty),false
otherwise:. -
#lineno ⇒ Integer
Returns the current line number for the stream; see Line Number.
-
#lineno=(integer) ⇒ Integer
Sets and returns the line number for the stream; see Line Number.
-
#path ⇒ String?
Returns the path associated with the IO, or
nil
if there is no path associated with the IO. -
#pid ⇒ Integer?
Returns the process ID of a child process associated with the stream, which will have been set by IO#popen, or
nil
if the stream was not created by IO#popen:. -
#tell ⇒ Integer
Returns the current position (in bytes) in
self
(see Position):. -
#pos=(new_position) ⇒ Object
Seeks to the given
new_position
(in bytes); see Position:. -
#pread(*args) ⇒ Object
Behaves like IO#readpartial, except that it:.
-
#print(*objects) ⇒ nil
Writes the given objects to the stream; returns
nil
. -
#printf(format_string, *objects) ⇒ nil
Formats and writes
objects
to the stream. -
#putc(object) ⇒ Object
Writes a character to the stream.
-
#puts(*objects) ⇒ nil
Writes the given
objects
to the stream, which must be open for writing; returnsnil
.\ Writes a newline after each that does not already end with a newline sequence. -
#pwrite(object, offset) ⇒ Integer
Behaves like IO#write, except that it:.
-
#read(maxlen = nil, out_string = nil) ⇒ nil
Reads bytes from the stream; the stream must be opened for reading (see Access Modes):.
-
#readbyte ⇒ Integer
Reads and returns the next byte (in range 0..255) from the stream; raises EOFError if already at end-of-stream.
-
#readchar ⇒ String
Reads and returns the next 1-character string from the stream; raises EOFError if already at end-of-stream.
-
#readlines(*args) ⇒ Object
Reads and returns all remaining line from the stream; does not modify
$_
. -
#readpartial(*args) ⇒ Object
Reads up to
maxlen
bytes from the stream; returns a string (either a new string or the givenout_string
). -
#reopen(*args) ⇒ Object
Reassociates the stream with another stream, which may be of a different class.
-
#rewind ⇒ 0
Repositions the stream to its beginning, setting both the position and the line number to zero; see Position and Line Number:.
-
#seek(offset, whence = IO::SEEK_SET) ⇒ 0
Seeks to the position given by integer
offset
(see Position) and constantwhence
, which is one of:. -
#set_encoding(*args) ⇒ Object
See Encodings.
-
#set_encoding_by_bom ⇒ Encoding?
If the stream begins with a BOM (byte order marker), consumes the BOM and sets the external encoding accordingly; returns the result encoding if found, or
nil
otherwise:. -
#stat ⇒ Object
Returns status information for ios as an object of type File::Stat.
-
#sync ⇒ Boolean
Returns the current sync mode of the stream.
- #sync=(sync) ⇒ Object
-
#sysread(*args) ⇒ Object
Behaves like IO#readpartial, except that it uses low-level system functions.
-
#sysseek(offset, whence = IO::SEEK_SET) ⇒ Integer
Behaves like IO#seek, except that it:.
-
#syswrite(object) ⇒ Integer
Writes the given
object
to self, which must be opened for writing (see Modes); returns the number bytes written. -
#tell ⇒ Integer
Returns the current position (in bytes) in
self
(see Position):. -
#timeout ⇒ nil
Get the internal timeout duration or nil if it was not set.
-
#timeout=(timeout) ⇒ Object
Sets the internal timeout to the specified duration or nil.
-
#to_io ⇒ self
Returns
self
. -
#path ⇒ String?
Returns the path associated with the IO, or
nil
if there is no path associated with the IO. -
#isatty ⇒ Boolean
Returns
true
if the stream is associated with a terminal device (tty),false
otherwise:. -
#ungetbyte(b) ⇒ Object
Pushes back (“unshifts”) the given data onto the stream’s buffer, placing the data so that it is next to be read; returns
nil
. -
#ungetc(c) ⇒ Object
Pushes back (“unshifts”) the given data onto the stream’s buffer, placing the data so that it is next to be read; returns
nil
. -
#wait(*args) ⇒ Object
Waits until the IO becomes ready for the specified events and returns the subset of events that become ready, or a falsy value when times out.
-
#wait_priority(*args) ⇒ Object
Waits until IO is priority and returns a truthy value or a falsy value when times out.
-
#wait_readable(*args) ⇒ Object
Waits until IO is readable and returns a truthy value, or a falsy value when times out.
-
#wait_writable(*args) ⇒ Object
Waits until IO is writable and returns a truthy value or a falsy value when times out.
-
#write(*objects) ⇒ Integer
Writes each of the given
objects
toself
, which must be opened for writing (see Access Modes); returns the total number bytes written; each ofobjects
that is not a string is converted via methodto_s
:.
Methods included from Enumerable
#all?, #any?, #chain, #chunk, #chunk_while, #collect, #collect_concat, #compact, #count, #cycle, #detect, #drop, #drop_while, #each_cons, #each_entry, #each_slice, #each_with_index, #each_with_object, #entries, #filter, #filter_map, #find, #find_all, #find_index, #first, #flat_map, #grep, #grep_v, #group_by, #include?, #inject, #lazy, #map, #max, #max_by, #member?, #min, #min_by, #minmax, #minmax_by, #none?, #one?, #partition, #reduce, #reject, #reverse_each, #select, #slice_after, #slice_before, #slice_when, #sort, #sort_by, #sum, #take, #take_while, #tally, #to_a, #to_h, #uniq, #zip
Constructor Details
#new(fd, mode = 'r', **opts) ⇒ IO
Creates and returns a new IO object (file stream) from a file descriptor.
IO.new may be useful for interaction with low-level libraries. For higher-level interactions, it may be simpler to create the file stream using File.open.
Argument fd
must be a valid file descriptor (integer):
path = 't.tmp'
fd = IO.sysopen(path) # => 3
IO.new(fd) # => #<IO:fd 3>
The new IO object does not inherit encoding (because the integer file descriptor does not have an encoding):
fd = IO.sysopen('t.rus', 'rb')
io = IO.new(fd)
io.external_encoding # => #<Encoding:UTF-8> # Not ASCII-8BIT.
Optional argument mode
(defaults to ‘r’) must specify a valid mode; see Access Modes:
IO.new(fd, 'w') # => #<IO:fd 3>
IO.new(fd, File::WRONLY) # => #<IO:fd 3>
Optional keyword arguments opts
specify:
Examples:
IO.new(fd, internal_encoding: nil) # => #<IO:fd 3>
IO.new(fd, autoclose: true) # => #<IO:fd 3>
9457 9458 9459 9460 9461 9462 9463 9464 9465 9466 9467 9468 9469 9470 9471 9472 9473 9474 9475 9476 9477 9478 9479 9480 9481 9482 9483 9484 9485 9486 9487 9488 9489 9490 9491 9492 9493 9494 9495 9496 9497 9498 9499 9500 9501 9502 9503 9504 9505 9506 9507 9508 9509 9510 9511 9512 9513 9514 9515 9516 9517 9518 9519 9520 9521 9522 9523 9524 9525 9526 9527 9528 |
# File 'io.c', line 9457
static VALUE
rb_io_initialize(int argc, VALUE *argv, VALUE io)
{
VALUE fnum, vmode;
rb_io_t *fp;
int fd, fmode, oflags = O_RDONLY;
struct rb_io_encoding convconfig;
VALUE opt;
#if defined(HAVE_FCNTL) && defined(F_GETFL)
int ofmode;
#else
struct stat st;
#endif
argc = rb_scan_args(argc, argv, "11:", &fnum, &vmode, &opt);
rb_io_extract_modeenc(&vmode, 0, opt, &oflags, &fmode, &convconfig);
fd = NUM2INT(fnum);
if (rb_reserved_fd_p(fd)) {
rb_raise(rb_eArgError, "The given fd is not accessible because RubyVM reserves it");
}
#if defined(HAVE_FCNTL) && defined(F_GETFL)
oflags = fcntl(fd, F_GETFL);
if (oflags == -1) rb_sys_fail(0);
#else
if (fstat(fd, &st) < 0) rb_sys_fail(0);
#endif
rb_update_max_fd(fd);
#if defined(HAVE_FCNTL) && defined(F_GETFL)
ofmode = rb_io_oflags_fmode(oflags);
if (NIL_P(vmode)) {
fmode = ofmode;
}
else if ((~ofmode & fmode) & FMODE_READWRITE) {
VALUE error = INT2FIX(EINVAL);
rb_exc_raise(rb_class_new_instance(1, &error, rb_eSystemCallError));
}
#endif
VALUE path = Qnil;
if (!NIL_P(opt)) {
if (rb_hash_aref(opt, sym_autoclose) == Qfalse) {
fmode |= FMODE_EXTERNAL;
}
path = rb_hash_aref(opt, RB_ID2SYM(idPath));
if (!NIL_P(path)) {
StringValue(path);
path = rb_str_new_frozen(path);
}
}
MakeOpenFile(io, fp);
fp->self = io;
fp->fd = fd;
fp->mode = fmode;
fp->encs = convconfig;
fp->pathv = path;
fp->timeout = Qnil;
clear_codeconv(fp);
io_check_tty(fp);
if (fileno(stdin) == fd)
fp->stdio_file = stdin;
else if (fileno(stdout) == fd)
fp->stdio_file = stdout;
else if (fileno(stderr) == fd)
fp->stdio_file = stderr;
if (fmode & FMODE_SETENC_BY_BOM) io_set_encoding_by_bom(io);
return io;
}
|
Class Method Details
.binread(path, length = nil, offset = 0) ⇒ String?
Behaves like IO.read, except that the stream is opened in binary mode with ASCII-8BIT encoding.
When called from class IO (but not subclasses of IO), this method has potential security vulnerabilities if called with untrusted input; see Command Injection.
12241 12242 12243 12244 12245 12246 12247 12248 12249 12250 12251 12252 12253 12254 12255 12256 12257 12258 12259 12260 12261 12262 12263 12264 12265 12266 12267 12268 12269 12270 12271 12272 12273 12274 12275 |
# File 'io.c', line 12241
static VALUE
rb_io_s_binread(int argc, VALUE *argv, VALUE io)
{
VALUE offset;
struct foreach_arg arg;
enum {
fmode = FMODE_READABLE|FMODE_BINMODE,
oflags = O_RDONLY
#ifdef O_BINARY
|O_BINARY
#endif
};
struct rb_io_encoding convconfig = {NULL, NULL, 0, Qnil};
rb_scan_args(argc, argv, "12", NULL, NULL, &offset);
FilePathValue(argv[0]);
convconfig.enc = rb_ascii8bit_encoding();
arg.io = rb_io_open_generic(io, argv[0], oflags, fmode, &convconfig, 0);
if (NIL_P(arg.io)) return Qnil;
arg.argv = argv+1;
arg.argc = (argc > 1) ? 1 : 0;
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);
}
}
return rb_ensure(io_s_read, (VALUE)&arg, rb_io_close, arg.io);
}
|
.binwrite(path, string, offset = 0) ⇒ Integer
Behaves like IO.write, except that the stream is opened in binary mode with ASCII-8BIT encoding.
When called from class IO (but not subclasses of IO), this method has potential security vulnerabilities if called with untrusted input; see Command Injection.
12395 12396 12397 12398 12399 |
# File 'io.c', line 12395
static VALUE
rb_io_s_binwrite(int argc, VALUE *argv, VALUE io)
{
return io_s_write(argc, argv, io, 1);
}
|
.copy_stream(src, dst, src_length = nil, src_offset = 0) ⇒ Integer
Copies from the given src
to the given dst
, returning the number of bytes copied.
-
The given
src
must be one of the following:-
The path to a readable file, from which source data is to be read.
-
An IO-like object, opened for reading and capable of responding to method
:readpartial
or method:read
.
-
-
The given
dst
must be one of the following:-
The path to a writable file, to which data is to be written.
-
An IO-like object, opened for writing and capable of responding to method
:write
.
-
The examples here use file t.txt
as source:
File.read('t.txt')
# => "First line\nSecond line\n\nThird line\nFourth line\n"
File.read('t.txt').size # => 47
If only arguments src
and dst
are given, the entire source stream is copied:
# Paths.
IO.copy_stream('t.txt', 't.tmp') # => 47
# IOs (recall that a File is also an IO).
src_io = File.open('t.txt', 'r') # => #<File:t.txt>
dst_io = File.open('t.tmp', 'w') # => #<File:t.tmp>
IO.copy_stream(src_io, dst_io) # => 47
src_io.close
dst_io.close
With argument src_length
a non-negative integer, no more than that many bytes are copied:
IO.copy_stream('t.txt', 't.tmp', 10) # => 10
File.read('t.tmp') # => "First line"
With argument src_offset
also given, the source stream is read beginning at that offset:
IO.copy_stream('t.txt', 't.tmp', 11, 11) # => 11
IO.read('t.tmp') # => "Second line"
13364 13365 13366 13367 13368 13369 13370 13371 13372 13373 13374 13375 13376 13377 13378 13379 13380 13381 13382 13383 13384 13385 13386 13387 13388 13389 13390 13391 13392 13393 |
# File 'io.c', line 13364
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;
st.src_fptr = NULL;
st.dst_fptr = NULL;
if (NIL_P(length))
st.copy_length = (rb_off_t)-1;
else
st.copy_length = NUM2OFFT(length);
if (NIL_P(src_offset))
st.src_offset = (rb_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);
}
|
.for_fd(fd, mode = 'r', **opts) ⇒ IO
Synonym for IO.new.
9656 9657 9658 9659 9660 9661 9662 |
# File 'io.c', line 9656
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;
}
|
.foreach(path, sep = $/, **opts) {|line| ... } ⇒ nil .foreach(path, limit, **opts) {|line| ... } ⇒ nil .foreach(path, sep, limit, **opts) {|line| ... } ⇒ nil .foreach(...) ⇒ Object
Calls the block with each successive line read from the stream.
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 that is the path to a file.
With only argument path
given, parses lines from the file at the given path
, as determined by the default line separator, and calls the block with each successive line:
File.foreach('t.txt') {|line| p line }
Output: the same as above.
For both forms, command and path, the remaining arguments are the same.
With argument sep
given, parses lines as determined by that line separator (see Line Separator):
File.foreach('t.txt', 'li') {|line| p line }
Output:
"First li"
"ne\nSecond li"
"ne\n\nThird li"
"ne\nFourth li"
"ne\n"
Each paragraph:
File.foreach('t.txt', '') {|paragraph| p paragraph }
Output:
"First line\nSecond line\n\n"
"Third line\nFourth line\n"
With argument limit
given, parses lines as determined by the default line separator and the given line-length limit (see Line Limit):
File.foreach('t.txt', 7) {|line| p line }
Output:
"First l"
"ine\n"
"Second "
"line\n"
"\n"
"Third l"
"ine\n"
"Fourth l"
"line\n"
With arguments sep
and limit
given, parses lines as determined by the given line separator and the given line-length limit (see Line Separator and Line Limit):
Optional keyword arguments opts
specify:
Returns an Enumerator if no block is given.
12041 12042 12043 12044 12045 12046 12047 12048 12049 12050 12051 12052 12053 12054 12055 12056 12057 |
# File 'io.c', line 12041
static VALUE
rb_io_s_foreach(int argc, VALUE *argv, VALUE self)
{
VALUE opt;
int orig_argc = argc;
struct foreach_arg arg;
struct getline_arg garg;
argc = rb_scan_args(argc, argv, "12:", NULL, NULL, NULL, &opt);
RETURN_ENUMERATOR(self, orig_argc, argv);
extract_getline_args(argc-1, argv+1, &garg);
open_key_args(self, argc, argv, opt, &arg);
if (NIL_P(arg.io)) return Qnil;
extract_getline_opts(opt, &garg);
check_getline_args(&garg.rs, &garg.limit, garg.io = arg.io);
return rb_ensure(io_s_foreach, (VALUE)&garg, rb_io_close, arg.io);
}
|
.new(*args) ⇒ Object
:nodoc:
9635 9636 9637 9638 9639 9640 9641 9642 9643 9644 9645 |
# File 'io.c', line 9635
static VALUE
rb_io_s_new(int argc, VALUE *argv, VALUE klass)
{
if (rb_block_given_p()) {
VALUE cname = rb_obj_as_string(klass);
rb_warn("%"PRIsVALUE"::new() does not take block; use %"PRIsVALUE"::open() instead",
cname, cname);
}
return rb_class_new_instance_kw(argc, argv, klass, RB_PASS_CALLED_KEYWORDS);
}
|
.open(*args) ⇒ Object
call-seq:
IO.open(fd, mode = 'r', **opts) -> io
IO.open(fd, mode = 'r', **opts) {|io| ... } -> object
Creates a new IO object, via IO.new with the given arguments.
With no block given, returns the IO object.
With a block given, calls the block with the IO object and returns the block’s value.
8147 8148 8149 8150 8151 8152 8153 8154 8155 8156 8157 |
# File 'io.c', line 8147
static VALUE
rb_io_s_open(int argc, VALUE *argv, VALUE klass)
{
VALUE io = rb_class_new_instance_kw(argc, argv, klass, RB_PASS_CALLED_KEYWORDS);
if (rb_block_given_p()) {
return rb_ensure(rb_yield, io, io_close, io);
}
return io;
}
|
.pipe(**opts) ⇒ Array .pipe(enc, **opts) ⇒ Array .pipe(ext_enc, int_enc, **opts) ⇒ Array .pipe(**opts) {|read_io, write_io| ... } ⇒ Object .pipe(enc, **opts) {|read_io, write_io| ... } ⇒ Object .pipe(ext_enc, int_enc, **opts) {|read_io, write_io| ... } ⇒ Object
Creates a pair of pipe endpoints, read_io
and write_io
, connected to each other.
If argument enc_string
is given, it must be a string containing one of:
-
The name of the encoding to be used as the external encoding.
-
The colon-separated names of two encodings to be used as the external and internal encodings.
If argument int_enc
is given, it must be an Encoding object or encoding name string that specifies the internal encoding to be used; if argument ext_enc
is also given, it must be an Encoding object or encoding name string that specifies the external encoding to be used.
The string read from read_io
is tagged with the external encoding; if an internal encoding is also specified, the string is converted to, and tagged with, that encoding.
If any encoding is specified, optional hash arguments specify the conversion option.
Optional keyword arguments opts
specify:
With no block given, returns the two endpoints in an array:
IO.pipe # => [#<IO:fd 4>, #<IO:fd 5>]
With a block given, calls the block with the two endpoints; closes both endpoints and returns the value of the block:
IO.pipe {|read_io, write_io| p read_io; p write_io }
Output:
#<IO:fd 6>
#<IO:fd 7>
Not available on all platforms.
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>
11827 11828 11829 11830 11831 11832 11833 11834 11835 11836 11837 11838 11839 11840 11841 11842 11843 11844 11845 11846 11847 11848 11849 11850 11851 11852 11853 11854 11855 11856 11857 11858 11859 11860 11861 11862 11863 11864 11865 11866 11867 11868 11869 11870 11871 11872 11873 11874 11875 11876 11877 11878 11879 11880 11881 11882 11883 11884 11885 11886 11887 11888 11889 11890 11891 11892 11893 11894 11895 11896 11897 11898 11899 11900 11901 11902 11903 11904 11905 11906 11907 11908 11909 11910 |
# File 'io.c', line 11827
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;
struct io_encoding_set_args ies_args;
int fmode = 0;
VALUE ret;
argc = rb_scan_args(argc, argv, "02:", &v1, &v2, &opt);
if (rb_pipe(pipes) < 0)
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);
ies_args.fptr = fptr;
ies_args.v1 = v1;
ies_args.v2 = v2;
ies_args.opt = opt;
rb_protect(io_encoding_set_v, (VALUE)&ies_args, &state);
if (state) {
close(pipes[1]);
io_close(r);
rb_jump_tag(state);
}
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);
if ((fmode & FMODE_BINMODE) && NIL_P(v1)) {
rb_io_ascii8bit_binmode(r);
rb_io_ascii8bit_binmode(w);
}
#if DEFAULT_TEXTMODE
if ((fptr->mode & FMODE_TEXTMODE) && (fmode & FMODE_BINMODE)) {
fptr->mode &= ~FMODE_TEXTMODE;
setmode(fptr->fd, O_BINARY);
}
#if RUBY_CRLF_ENVIRONMENT
if (fptr->encs.ecflags & ECONV_DEFAULT_NEWLINE_DECORATOR) {
fptr->encs.ecflags |= ECONV_UNIVERSAL_NEWLINE_DECORATOR;
}
#endif
#endif
fptr->mode |= fmode;
#if DEFAULT_TEXTMODE
if ((fptr2->mode & FMODE_TEXTMODE) && (fmode & FMODE_BINMODE)) {
fptr2->mode &= ~FMODE_TEXTMODE;
setmode(fptr2->fd, O_BINARY);
}
#endif
fptr2->mode |= fmode;
ret = rb_assoc_new(r, w);
if (rb_block_given_p()) {
VALUE rw[2];
rw[0] = r;
rw[1] = w;
return rb_ensure(rb_yield, ret, pipe_pair_close, (VALUE)rw);
}
return ret;
}
|
.popen(env = {}, cmd, mode = 'r', **opts) ⇒ IO .popen(env = ) { ... } ⇒ Object
Executes the given command cmd
as a subprocess whose $stdin and $stdout are connected to a new stream io
.
This method has potential security vulnerabilities if called with untrusted input; see Command Injection.
If no block is given, returns the new stream, which depending on given mode
may be open for reading, writing, or both. The stream should be explicitly closed (eventually) to avoid resource leaks.
If a block is given, the stream is passed to the block (again, open for reading, writing, or both); when the block exits, the stream is closed, and the block’s value is assigned to global variable $?
and returned.
Optional argument mode
may be any valid IO mode. See Access Modes.
Required argument cmd
determines which of the following occurs:
-
The process forks.
-
A specified program runs in a shell.
-
A specified program runs with specified arguments.
-
A specified program runs with specified arguments and a specified
argv0
.
Each of these is detailed below.
The optional hash argument env
specifies name/value pairs that are to be added to the environment variables for the subprocess:
IO.popen({'FOO' => 'bar'}, 'ruby', 'r+') do |pipe|
pipe.puts 'puts ENV["FOO"]'
pipe.close_write
pipe.gets
end => "bar\n"
Optional keyword arguments opts
specify:
-
Options for Kernel#spawn.
Forked Process
When argument cmd
is the 1-character string '-'
, causes the process to fork:
IO.popen('-') do |pipe|
if pipe
$stderr.puts "In parent, child pid is #{pipe.pid}\n"
else
$stderr.puts "In child, pid is #{$$}\n"
end
end
Output:
In parent, child pid is 26253
In child, pid is 26253
Note that this is not supported on all platforms.
Shell Subprocess
When argument cmd
is a single string (but not '-'
), the program named cmd
is run as a shell command:
IO.popen('uname') do |pipe|
pipe.readlines
end
Output:
["Linux\n"]
Another example:
IO.popen('/bin/sh', 'r+') do |pipe|
pipe.puts('ls')
pipe.close_write
$stderr.puts pipe.readlines.size
end
Output:
213
Program Subprocess
When argument cmd
is an array of strings, the program named cmd[0]
is run with all elements of cmd
as its arguments:
IO.popen(['du', '..', '.']) do |pipe|
$stderr.puts pipe.readlines.size
end
Output:
1111
Program Subprocess with argv0
When argument cmd
is an array whose first element is a 2-element string array and whose remaining elements (if any) are strings:
-
cmd[0][0]
(the first string in the nested array) is the name of a program that is run. -
cmd[0][1]
(the second string in the nested array) is set as the program’sargv[0]
. -
cmd[1..-1]
(the strings in the outer array) are the program’s arguments.
Example (sets $0
to ‘foo’):
IO.popen([['/bin/sh', 'foo'], '-c', 'echo $0']).read # => "foo\n"
Some Special Examples
# Set IO encoding.
IO.popen("nkf -e filename", :external_encoding=>"EUC-JP") {|nkf_io|
euc_jp_string = nkf_io.read
}
# Merge standard output and standard error using Kernel#spawn option. See Kernel#spawn.
IO.popen(["ls", "/", :err=>[:child, :out]]) do |io|
ls_result_with_error = io.read
end
# Use mixture of spawn options and IO options.
IO.popen(["ls", "/"], :err=>[:child, :out]) do |io|
ls_result_with_error = io.read
end
f = IO.popen("uname")
p f.readlines
f.close
puts "Parent is #{Process.pid}"
IO.popen("date") {|f| puts f.gets }
IO.popen("-") {|f| $stderr.puts "#{Process.pid} is here, f is #{f.inspect}"}
p $?
IO.popen(%w"sed -e s|^|<foo>| -e s&$&;zot;&", "r+") {|f|
f.puts "bar"; f.close_write; puts f.gets
}
Output (from last section):
["Linux\n"]
Parent is 21346
Thu Jan 15 22:41:19 JST 2009
21346 is here, f is #<IO:fd 3>
21352 is here, f is nil
#<Process::Status: pid 21352 exit 0>
<foo>bar;zot;
Raises exceptions that IO.pipe and Kernel.spawn raise.
7946 7947 7948 7949 7950 7951 7952 7953 7954 7955 7956 7957 7958 7959 7960 7961 7962 7963 7964 7965 7966 |
# File 'io.c', line 7946
static VALUE
rb_io_s_popen(int argc, VALUE *argv, VALUE klass)
{
VALUE pname, pmode = Qnil, opt = Qnil, env = Qnil;
if (argc > 1 && !NIL_P(opt = rb_check_hash_type(argv[argc-1]))) --argc;
if (argc > 1 && !NIL_P(env = rb_check_hash_type(argv[0]))) --argc, ++argv;
switch (argc) {
case 2:
pmode = argv[1];
case 1:
pname = argv[0];
break;
default:
{
int ex = !NIL_P(opt);
rb_error_arity(argc + ex, 1 + ex, 2 + ex);
}
}
return popen_finish(rb_io_popen(pname, pmode, env, opt), klass);
}
|
.read(path, length = nil, offset = 0, **opts) ⇒ String?
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 that is the path to a file.
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.
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:
12199 12200 12201 12202 12203 12204 12205 12206 12207 12208 12209 12210 12211 12212 12213 12214 12215 12216 12217 12218 12219 12220 12221 12222 12223 12224 12225 12226 |
# File 'io.c', line 12199
static VALUE
rb_io_s_read(int argc, VALUE *argv, VALUE io)
{
VALUE opt, offset;
long off;
struct foreach_arg arg;
argc = rb_scan_args(argc, argv, "13:", NULL, NULL, &offset, NULL, &opt);
if (!NIL_P(offset) && (off = NUM2LONG(offset)) < 0) {
rb_raise(rb_eArgError, "negative offset %ld given", off);
}
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);
}
|
.readlines(path, sep = $/, **opts) ⇒ Array .readlines(path, limit, **opts) ⇒ Array .readlines(path, sep, limit, **opts) ⇒ Array
Returns an array of all lines read from the stream.
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 that is the path to a file.
With only argument path
given, parses lines from the file at the given path
, as determined by the default line separator, and returns those lines in an array:
IO.readlines('t.txt')
# => ["First line\n", "Second line\n", "\n", "Third line\n", "Fourth line\n"]
With argument sep
given, parses lines as determined by that line separator (see Line Separator):
# Ordinary separator.
IO.readlines('t.txt', 'li')
# =>["First li", "ne\nSecond li", "ne\n\nThird li", "ne\nFourth li", "ne\n"]
# Get-paragraphs separator.
IO.readlines('t.txt', '')
# => ["First line\nSecond line\n\n", "Third line\nFourth line\n"]
# Get-all separator.
IO.readlines('t.txt', nil)
# => ["First line\nSecond line\n\nThird line\nFourth line\n"]
With argument limit
given, parses lines as determined by the default line separator and the given line-length limit (see Line Limit):
IO.readlines('t.txt', 7)
# => ["First l", "ine\n", "Second ", "line\n", "\n", "Third l", "ine\n", "Fourth ", "line\n"]
With arguments sep
and limit
given, parses lines as determined by the given line separator and the given line-length limit (see Line Separator and Line Limit):
Optional keyword arguments opts
specify:
12120 12121 12122 12123 12124 12125 12126 12127 12128 12129 12130 12131 12132 12133 12134 |
# File 'io.c', line 12120
static VALUE
rb_io_s_readlines(int argc, VALUE *argv, VALUE io)
{
VALUE opt;
struct foreach_arg arg;
struct getline_arg garg;
argc = rb_scan_args(argc, argv, "12:", NULL, NULL, NULL, &opt);
extract_getline_args(argc-1, argv+1, &garg);
open_key_args(io, argc, argv, opt, &arg);
if (NIL_P(arg.io)) return Qnil;
extract_getline_opts(opt, &garg);
check_getline_args(&garg.rs, &garg.limit, garg.io = arg.io);
return rb_ensure(io_s_readlines, (VALUE)&garg, rb_io_close, arg.io);
}
|
.select(read_ios, write_ios = [], error_ios = [], timeout = nil) ⇒ Array?
Invokes system call select(2), which monitors multiple file descriptors, waiting until one or more of the file descriptors becomes ready for some class of I/O operation.
Not implemented on all platforms.
Each of the arguments read_ios
, write_ios
, and error_ios
is an array of IO objects.
Argument timeout
is an integer timeout interval in seconds.
The method monitors the IO objects given in all three arrays, waiting for some to be ready; returns a 3-element array whose elements are:
-
An array of the objects in
read_ios
that are ready for reading. -
An array of the objects in
write_ios
that are ready for writing. -
An array of the objects in
error_ios
have pending exceptions.
If no object becomes ready within the given timeout
, nil
is returned.
IO.select peeks the buffer of IO objects for testing readability. If the IO buffer is not empty, IO.select immediately notifies readability. This “peek” only happens for IO objects. It does not happen for IO-like objects such as OpenSSL::SSL::SSLSocket.
The best way to use IO.select is invoking it after non-blocking methods such as #read_nonblock, #write_nonblock, etc. The methods raise an exception which is extended by IO::WaitReadable or IO::WaitWritable. The modules notify how the caller should wait with IO.select. If IO::WaitReadable is raised, the caller should wait for reading. If IO::WaitWritable is raised, the caller should wait for writing.
So, blocking read (#readpartial) can be emulated using #read_nonblock and IO.select as follows:
begin
result = io_like.read_nonblock(maxlen)
rescue IO::WaitReadable
IO.select([io_like])
retry
rescue IO::WaitWritable
IO.select(nil, [io_like])
retry
end
Especially, the combination of non-blocking methods and IO.select is preferred for IO like objects such as OpenSSL::SSL::SSLSocket. It has #to_io method to return underlying IO object. IO.select calls #to_io to obtain the file descriptor to wait.
This means that readability notified by IO.select doesn’t mean readability from OpenSSL::SSL::SSLSocket object.
The most likely situation is that OpenSSL::SSL::SSLSocket buffers some data. IO.select doesn’t see the buffer. So IO.select can block when OpenSSL::SSL::SSLSocket#readpartial doesn’t block.
However, several more complicated situations exist.
SSL is a protocol which is sequence of records. The record consists of multiple bytes. So, the remote side of SSL sends a partial record, IO.select notifies readability but OpenSSL::SSL::SSLSocket cannot decrypt a byte and OpenSSL::SSL::SSLSocket#readpartial will block.
Also, the remote side can request SSL renegotiation which forces the local SSL engine to write some data. This means OpenSSL::SSL::SSLSocket#readpartial may invoke #write system call and it can block. In such a situation, OpenSSL::SSL::SSLSocket#read_nonblock raises IO::WaitWritable instead of blocking. So, the caller should wait for ready for writability as above example.
The combination of non-blocking methods and IO.select is also useful for streams such as tty, pipe socket socket when multiple processes read from a stream.
Finally, Linux kernel developers don’t guarantee that readability of select(2) means readability of following read(2) even for a single process; see select(2)
Invoking IO.select before IO#readpartial works well as usual. However it is not the best way to use IO.select.
The writability notified by select(2) doesn’t show how many bytes are writable. IO#write method blocks until given whole string is written. So, IO#write(two or more bytes)
can block after writability is notified by IO.select. IO#write_nonblock is required to avoid the blocking.
Blocking write (#write) can be emulated using #write_nonblock and IO.select as follows: IO::WaitReadable should also be rescued for SSL renegotiation in OpenSSL::SSL::SSLSocket.
while 0 < string.bytesize
begin
written = io_like.write_nonblock(string)
rescue IO::WaitReadable
IO.select([io_like])
retry
rescue IO::WaitWritable
IO.select(nil, [io_like])
retry
end
string = string.byteslice(written..-1)
end
Example:
rp, wp = IO.pipe
mesg = "ping "
100.times {
# IO.select follows IO#read. Not the best way to use IO.select.
rs, ws, = IO.select([rp], [wp])
if r = rs[0]
ret = r.read(5)
print ret
case ret
when /ping/
mesg = "pong\n"
when /pong/
mesg = "ping "
end
end
if w = ws[0]
w.write(mesg)
end
}
Output:
ping pong
ping pong
ping pong
(snipped)
ping
11073 11074 11075 11076 11077 11078 11079 11080 11081 11082 11083 11084 11085 11086 11087 11088 11089 11090 11091 11092 11093 11094 11095 11096 11097 11098 11099 11100 11101 |
# File 'io.c', line 11073
static VALUE
rb_f_select(int argc, VALUE *argv, VALUE obj)
{
VALUE scheduler = rb_fiber_scheduler_current();
if (scheduler != Qnil) {
// It's optionally supported.
VALUE result = rb_fiber_scheduler_io_selectv(scheduler, argc, argv);
if (!UNDEF_P(result)) return result;
}
VALUE timeout;
struct select_args args;
struct timeval timerec;
int i;
rb_scan_args(argc, argv, "13", &args.read, &args.write, &args.except, &timeout);
if (NIL_P(timeout)) {
args.timeout = 0;
}
else {
timerec = rb_time_interval(timeout);
args.timeout = &timerec;
}
for (i = 0; i < numberof(args.fdsets); ++i)
rb_fd_init(&args.fdsets[i]);
return rb_ensure(select_call, (VALUE)&args, select_end, (VALUE)&args);
}
|
.sysopen(path, mode = 'r', perm = 0666) ⇒ Integer
Opens the file at the given path with the given mode and permissions; returns the integer file descriptor.
If the file is to be readable, it must exist; if the file is to be writable and does not exist, it is created with the given permissions:
File.write('t.tmp', '') # => 0
IO.sysopen('t.tmp') # => 8
IO.sysopen('t.tmp', 'w') # => 9
8177 8178 8179 8180 8181 8182 8183 8184 8185 8186 8187 8188 8189 8190 8191 8192 8193 8194 8195 8196 8197 8198 8199 8200 8201 8202 |
# File 'io.c', line 8177
static VALUE
rb_io_s_sysopen(int argc, VALUE *argv, VALUE _)
{
VALUE fname, vmode, vperm;
VALUE intmode;
int oflags, fd;
mode_t perm;
rb_scan_args(argc, argv, "12", &fname, &vmode, &vperm);
FilePathValue(fname);
if (NIL_P(vmode))
oflags = O_RDONLY;
else if (!NIL_P(intmode = rb_check_to_integer(vmode, "to_int")))
oflags = NUM2INT(intmode);
else {
SafeStringValue(vmode);
oflags = rb_io_modestr_oflags(StringValueCStr(vmode));
}
if (NIL_P(vperm)) perm = 0666;
else perm = NUM2MODET(vperm);
RB_GC_GUARD(fname) = rb_str_new4(fname);
fd = rb_sysopen(fname, oflags, perm);
return INT2NUM(fd);
}
|
.try_convert(object) ⇒ nil
893 894 895 896 897 |
# File 'io.c', line 893
static VALUE
rb_io_s_try_convert(VALUE dummy, VALUE io)
{
return rb_io_check_io(io);
}
|
.write(path, data, offset = 0, **opts) ⇒ Integer
Opens the stream, writes the given data
to it, and closes the stream; returns the number of bytes written.
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 that is the path to a file.
With only argument path
given, writes the given data
to the file at that path:
IO.write('t.tmp', 'abc') # => 3
File.read('t.tmp') # => "abc"
If offset
is zero (the default), the file is overwritten:
IO.write('t.tmp', 'A') # => 1
File.read('t.tmp') # => "A"
If offset
in within the file content, the file is partly overwritten:
IO.write('t.tmp', 'abcdef') # => 3
File.read('t.tmp') # => "abcdef"
# Offset within content.
IO.write('t.tmp', '012', 2) # => 3
File.read('t.tmp') # => "ab012f"
If offset
is outside the file content, the file is padded with null characters "\u0000"
:
IO.write('t.tmp', 'xyz', 10) # => 3
File.read('t.tmp') # => "ab012f\u0000\u0000\u0000\u0000xyz"
Optional keyword arguments opts
specify:
12376 12377 12378 12379 12380 |
# File 'io.c', line 12376
static VALUE
rb_io_s_write(int argc, VALUE *argv, VALUE io)
{
return io_s_write(argc, argv, io, 0);
}
|
Instance Method Details
#<<(object) ⇒ self
Writes the given object
to self
, which must be opened for writing (see Access Modes); returns self
; if object
is not a string, it is converted via method to_s
:
$stdout << 'Hello' << ', ' << 'World!' << "\n"
$stdout << 'foo' << :bar << 2 << "\n"
Output:
Hello, World!
foobar2
2322 2323 2324 2325 2326 2327 |
# File 'io.c', line 2322
VALUE
rb_io_addstr(VALUE io, VALUE str)
{
rb_io_write(io, str);
return io;
}
|
#advise(advice, offset = 0, len = 0) ⇒ nil
Invokes Posix system call posix_fadvise(2), which announces an intention to access data from the current file in a particular manner.
The arguments and results are platform-dependent.
The relevant data is specified by:
-
offset
: The offset of the first byte of data. -
len
: The number of bytes to be accessed; iflen
is zero, or is larger than the number of bytes remaining, all remaining bytes will be accessed.
Argument advice
is one of the following symbols:
-
:normal
: The application has no advice to give about its access pattern for the specified data. If no advice is given for an open file, this is the default assumption. -
:sequential
: The application expects to access the specified data sequentially (with lower offsets read before higher ones). -
:random
: The specified data will be accessed in random order. -
:noreuse
: The specified data will be accessed only once. -
:willneed
: The specified data will be accessed in the near future. -
:dontneed
: The specified data will not be accessed in the near future.
Not implemented on all platforms.
10900 10901 10902 10903 10904 10905 10906 10907 10908 10909 10910 10911 10912 10913 10914 10915 10916 10917 10918 10919 10920 10921 10922 |
# File 'io.c', line 10900
static VALUE
rb_io_advise(int argc, VALUE *argv, VALUE io)
{
VALUE advice, offset, len;
rb_off_t off, l;
rb_io_t *fptr;
rb_scan_args(argc, argv, "12", &advice, &offset, &len);
advice_arg_check(advice);
io = GetWriteIO(io);
GetOpenFile(io, fptr);
off = NIL_P(offset) ? 0 : NUM2OFFT(offset);
l = NIL_P(len) ? 0 : NUM2OFFT(len);
#ifdef HAVE_POSIX_FADVISE
return do_io_advise(fptr, advice, off, l);
#else
((void)off, (void)l); /* Ignore all hint */
return Qnil;
#endif
}
|
#autoclose=(bool) ⇒ Boolean
9697 9698 9699 9700 9701 9702 9703 9704 9705 9706 9707 |
# File 'io.c', line 9697
static VALUE
rb_io_set_autoclose(VALUE io, VALUE autoclose)
{
rb_io_t *fptr;
GetOpenFile(io, fptr);
if (!RTEST(autoclose))
fptr->mode |= FMODE_EXTERNAL;
else
fptr->mode &= ~FMODE_EXTERNAL;
return autoclose;
}
|
#autoclose? ⇒ Boolean
Returns true
if the underlying file descriptor of ios will be closed at its finalization or at calling #close, otherwise false
.
9672 9673 9674 9675 9676 9677 9678 |
# File 'io.c', line 9672
static VALUE
rb_io_autoclose_p(VALUE io)
{
rb_io_t *fptr = RFILE(io)->fptr;
rb_io_check_closed(fptr);
return RBOOL(!(fptr->mode & FMODE_EXTERNAL));
}
|
#binmode ⇒ self
Sets the stream’s data mode as binary (see Data Mode).
A stream’s data mode may not be changed from binary to text.
6378 6379 6380 6381 6382 6383 6384 6385 6386 6387 6388 6389 |
# File 'io.c', line 6378
static VALUE
rb_io_binmode_m(VALUE io)
{
VALUE write_io;
rb_io_ascii8bit_binmode(io);
write_io = GetWriteIO(io);
if (write_io != io)
rb_io_ascii8bit_binmode(write_io);
return io;
}
|
#binmode? ⇒ Boolean
Returns true
if the stream is on binary mode, false
otherwise. See Data Mode.
6399 6400 6401 6402 6403 6404 6405 |
# File 'io.c', line 6399
static VALUE
rb_io_binmode_p(VALUE io)
{
rb_io_t *fptr;
GetOpenFile(io, fptr);
return RBOOL(fptr->mode & FMODE_BINMODE);
}
|
#close ⇒ nil
Closes the stream for both reading and writing if open for either or both; returns nil
. See Open and Closed Streams.
If the stream is open for writing, flushes any buffered writes to the operating system before closing.
If the stream was opened by IO.popen, sets global variable $?
(child exit status).
Example:
IO.popen('ruby', 'r+') do |pipe|
puts pipe.closed?
pipe.close
puts $?
puts pipe.closed?
end
Output:
false
pid 13760 exit 0
true
Related: IO#close_read, IO#close_write, IO#closed?.
5776 5777 5778 5779 5780 5781 5782 5783 5784 5785 |
# File 'io.c', line 5776
static VALUE
rb_io_close_m(VALUE io)
{
rb_io_t *fptr = rb_io_get_fptr(io);
if (fptr->fd < 0) {
return Qnil;
}
rb_io_close(io);
return Qnil;
}
|
#close_on_exec=(bool) ⇒ Boolean
Sets a close-on-exec flag.
f = File.open(File::NULL)
f.close_on_exec = true
system("cat", "/proc/self/fd/#{f.fileno}") # cat: /proc/self/fd/3: No such file or directory
f.closed? #=> false
Ruby sets close-on-exec flags of all file descriptors by default since Ruby 2.0.0. So you don’t need to set by yourself. Also, unsetting a close-on-exec flag can cause file descriptor leak if another thread use fork() and exec() (via system() method for example). If you really needs file descriptor inheritance to child process, use spawn()‘s argument such as fd=>fd.
5343 5344 5345 5346 5347 5348 5349 5350 5351 5352 5353 5354 5355 5356 5357 5358 5359 5360 5361 5362 5363 5364 5365 5366 5367 5368 5369 5370 5371 5372 5373 5374 5375 |
# File 'io.c', line 5343
static VALUE
rb_io_set_close_on_exec(VALUE io, VALUE arg)
{
int flag = RTEST(arg) ? FD_CLOEXEC : 0;
rb_io_t *fptr;
VALUE write_io;
int fd, ret;
write_io = GetWriteIO(io);
if (io != write_io) {
GetOpenFile(write_io, fptr);
if (fptr && 0 <= (fd = fptr->fd)) {
if ((ret = fcntl(fptr->fd, F_GETFD)) == -1) rb_sys_fail_path(fptr->pathv);
if ((ret & FD_CLOEXEC) != flag) {
ret = (ret & ~FD_CLOEXEC) | flag;
ret = fcntl(fd, F_SETFD, ret);
if (ret != 0) rb_sys_fail_path(fptr->pathv);
}
}
}
GetOpenFile(io, fptr);
if (fptr && 0 <= (fd = fptr->fd)) {
if ((ret = fcntl(fd, F_GETFD)) == -1) rb_sys_fail_path(fptr->pathv);
if ((ret & FD_CLOEXEC) != flag) {
ret = (ret & ~FD_CLOEXEC) | flag;
ret = fcntl(fd, F_SETFD, ret);
if (ret != 0) rb_sys_fail_path(fptr->pathv);
}
}
return Qnil;
}
|
#close_on_exec? ⇒ Boolean
5295 5296 5297 5298 5299 5300 5301 5302 5303 5304 5305 5306 5307 5308 5309 5310 5311 5312 5313 5314 5315 5316 5317 |
# File 'io.c', line 5295
static VALUE
rb_io_close_on_exec_p(VALUE io)
{
rb_io_t *fptr;
VALUE write_io;
int fd, ret;
write_io = GetWriteIO(io);
if (io != write_io) {
GetOpenFile(write_io, fptr);
if (fptr && 0 <= (fd = fptr->fd)) {
if ((ret = fcntl(fd, F_GETFD)) == -1) rb_sys_fail_path(fptr->pathv);
if (!(ret & FD_CLOEXEC)) return Qfalse;
}
}
GetOpenFile(io, fptr);
if (fptr && 0 <= (fd = fptr->fd)) {
if ((ret = fcntl(fd, F_GETFD)) == -1) rb_sys_fail_path(fptr->pathv);
if (!(ret & FD_CLOEXEC)) return Qfalse;
}
return Qtrue;
}
|
#close_read ⇒ nil
Closes the stream for reading if open for reading; returns nil
. See Open and Closed Streams.
If the stream was opened by IO.popen and is also closed for writing, sets global variable $?
(child exit status).
Example:
IO.popen('ruby', 'r+') do |pipe|
puts pipe.closed?
pipe.close_write
puts pipe.closed?
pipe.close_read
puts $?
puts pipe.closed?
end
Output:
false
false
pid 14748 exit 0
true
Related: IO#close, IO#close_write, IO#closed?.
5892 5893 5894 5895 5896 5897 5898 5899 5900 5901 5902 5903 5904 5905 5906 5907 5908 5909 5910 5911 5912 5913 5914 5915 5916 5917 5918 5919 5920 5921 5922 5923 5924 5925 5926 5927 5928 5929 5930 5931 |
# File 'io.c', line 5892
static VALUE
rb_io_close_read(VALUE io)
{
rb_io_t *fptr;
VALUE write_io;
fptr = rb_io_get_fptr(rb_io_taint_check(io));
if (fptr->fd < 0) return Qnil;
if (is_socket(fptr->fd, fptr->pathv)) {
#ifndef SHUT_RD
# define SHUT_RD 0
#endif
if (shutdown(fptr->fd, SHUT_RD) < 0)
rb_sys_fail_path(fptr->pathv);
fptr->mode &= ~FMODE_READABLE;
if (!(fptr->mode & FMODE_WRITABLE))
return rb_io_close(io);
return Qnil;
}
write_io = GetWriteIO(io);
if (io != write_io) {
rb_io_t *wfptr;
wfptr = rb_io_get_fptr(rb_io_taint_check(write_io));
wfptr->pid = fptr->pid;
fptr->pid = 0;
RFILE(io)->fptr = wfptr;
/* bind to write_io temporarily to get rid of memory/fd leak */
fptr->tied_io_for_writing = 0;
RFILE(write_io)->fptr = fptr;
rb_io_fptr_cleanup(fptr, FALSE);
/* should not finalize fptr because another thread may be reading it */
return Qnil;
}
if ((fptr->mode & (FMODE_DUPLEX|FMODE_WRITABLE)) == FMODE_WRITABLE) {
rb_raise(rb_eIOError, "closing non-duplex IO for reading");
}
return rb_io_close(io);
}
|
#close_write ⇒ nil
Closes the stream for writing if open for writing; returns nil
. See Open and Closed Streams.
Flushes any buffered writes to the operating system before closing.
If the stream was opened by IO.popen and is also closed for reading, sets global variable $?
(child exit status).
IO.popen('ruby', 'r+') do |pipe|
puts pipe.closed?
pipe.close_read
puts pipe.closed?
pipe.close_write
puts $?
puts pipe.closed?
end
Output:
false
false
pid 15044 exit 0
true
Related: IO#close, IO#close_read, IO#closed?.
5965 5966 5967 5968 5969 5970 5971 5972 5973 5974 5975 5976 5977 5978 5979 5980 5981 5982 5983 5984 5985 5986 5987 5988 5989 5990 5991 5992 5993 5994 5995 5996 |
# File 'io.c', line 5965
static VALUE
rb_io_close_write(VALUE io)
{
rb_io_t *fptr;
VALUE write_io;
write_io = GetWriteIO(io);
fptr = rb_io_get_fptr(rb_io_taint_check(write_io));
if (fptr->fd < 0) return Qnil;
if (is_socket(fptr->fd, fptr->pathv)) {
#ifndef SHUT_WR
# define SHUT_WR 1
#endif
if (shutdown(fptr->fd, SHUT_WR) < 0)
rb_sys_fail_path(fptr->pathv);
fptr->mode &= ~FMODE_WRITABLE;
if (!(fptr->mode & FMODE_READABLE))
return rb_io_close(write_io);
return Qnil;
}
if ((fptr->mode & (FMODE_DUPLEX|FMODE_READABLE)) == FMODE_READABLE) {
rb_raise(rb_eIOError, "closing non-duplex IO for writing");
}
if (io != write_io) {
fptr = rb_io_get_fptr(rb_io_taint_check(io));
fptr->tied_io_for_writing = 0;
}
rb_io_close(write_io);
return Qnil;
}
|
#closed? ⇒ Boolean
Returns true
if the stream is closed for both reading and writing, false
otherwise. See Open and Closed Streams.
IO.popen('ruby', 'r+') do |pipe|
puts pipe.closed?
pipe.close_read
puts pipe.closed?
pipe.close_write
puts pipe.closed?
end
Output:
false
false
true
Related: IO#close_read, IO#close_write, IO#close.
5841 5842 5843 5844 5845 5846 5847 5848 5849 5850 5851 5852 5853 5854 5855 5856 5857 5858 |
# File 'io.c', line 5841
VALUE
rb_io_closed_p(VALUE io)
{
rb_io_t *fptr;
VALUE write_io;
rb_io_t *write_fptr;
write_io = GetWriteIO(io);
if (io != write_io) {
write_fptr = RFILE(write_io)->fptr;
if (write_fptr && 0 <= write_fptr->fd) {
return Qfalse;
}
}
fptr = rb_io_get_fptr(io);
return RBOOL(0 > fptr->fd);
}
|
#each_line(sep = $/, chomp: false) {|line| ... } ⇒ self #each_line(limit, chomp: false) {|line| ... } ⇒ self #each_line(sep, limit, chomp: false) {|line| ... } ⇒ self #each_line ⇒ Object
Calls the block with each remaining line read from the stream; returns self
. Does nothing if already at end-of-stream; See Line IO.
With no arguments given, reads lines as determined by line separator $/
:
f = File.new('t.txt')
f.each_line {|line| p line }
f.each_line {|line| fail 'Cannot happen' }
f.close
Output:
"First line\n"
"Second line\n"
"\n"
"Fourth line\n"
"Fifth line\n"
With only string argument sep
given, reads lines as determined by line separator sep
; see Line Separator:
f = File.new('t.txt')
f.each_line('li') {|line| p line }
f.close
Output:
"First li"
"ne\nSecond li"
"ne\n\nFourth li"
"ne\nFifth li"
"ne\n"
The two special values for sep
are honored:
f = File.new('t.txt')
# Get all into one string.
f.each_line(nil) {|line| p line }
f.close
Output:
"First line\nSecond line\n\nFourth line\nFifth line\n"
f.rewind
# Get paragraphs (up to two line separators).
f.each_line('') {|line| p line }
Output:
"First line\nSecond line\n\n"
"Fourth line\nFifth line\n"
With only integer argument limit
given, limits the number of bytes in each line; see Line Limit:
f = File.new('t.txt')
f.each_line(8) {|line| p line }
f.close
Output:
"First li"
"ne\n"
"Second l"
"ine\n"
"\n"
"Fourth l"
"ine\n"
"Fifth li"
"ne\n"
With arguments sep
and limit
given, combines the two behaviors:
-
Calls with the next line as determined by line separator
sep
. -
But returns no more bytes than are allowed by the limit.
Optional keyword argument chomp
specifies whether line separators are to be omitted:
f = File.new('t.txt')
f.each_line(chomp: true) {|line| p line }
f.close
Output:
"First line"
"Second line"
""
"Fourth line"
"Fifth line"
Returns an Enumerator if no block is given.
4648 4649 4650 4651 4652 4653 4654 4655 4656 4657 4658 4659 4660 4661 4662 |
# File 'io.c', line 4648
static VALUE
rb_io_each_line(int argc, VALUE *argv, VALUE io)
{
VALUE str;
struct getline_arg args;
RETURN_ENUMERATOR(io, argc, argv);
prepare_getline_args(argc, argv, &args, io);
if (args.limit == 0)
rb_raise(rb_eArgError, "invalid limit: 0 for each_line");
while (!NIL_P(str = rb_io_getline_1(args.rs, args.limit, args.chomp, io))) {
rb_yield(str);
}
return io;
}
|
#each_byte {|byte| ... } ⇒ self #each_byte ⇒ Object
4684 4685 4686 4687 4688 4689 4690 4691 4692 4693 4694 4695 4696 4697 4698 4699 4700 4701 4702 4703 |
# File 'io.c', line 4684
static VALUE
rb_io_each_byte(VALUE io)
{
rb_io_t *fptr;
RETURN_ENUMERATOR(io, 0, 0);
GetOpenFile(io, fptr);
do {
while (fptr->rbuf.len > 0) {
char *p = fptr->rbuf.ptr + fptr->rbuf.off++;
fptr->rbuf.len--;
rb_yield(INT2FIX(*p & 0xff));
rb_io_check_byte_readable(fptr);
errno = 0;
}
READ_CHECK(fptr);
} while (io_fillbuf(fptr) >= 0);
return io;
}
|
#each_char {|c| ... } ⇒ self #each_char ⇒ Object
Calls the given block with each character in the stream; returns self
. See Character IO.
f = File.new('t.rus')
a = []
f.each_char {|c| a << c.ord }
a # => [1090, 1077, 1089, 1090]
f.close
Returns an Enumerator if no block is given.
Related: IO#each_byte, IO#each_codepoint.
4832 4833 4834 4835 4836 4837 4838 4839 4840 4841 4842 4843 4844 4845 4846 4847 4848 4849 |
# File 'io.c', line 4832
static VALUE
rb_io_each_char(VALUE io)
{
rb_io_t *fptr;
rb_encoding *enc;
VALUE c;
RETURN_ENUMERATOR(io, 0, 0);
GetOpenFile(io, fptr);
rb_io_check_char_readable(fptr);
enc = io_input_encoding(fptr);
READ_CHECK(fptr);
while (!NIL_P(c = io_getc(fptr, enc))) {
rb_yield(c);
}
return io;
}
|
#each_codepoint {|c| ... } ⇒ self #each_codepoint ⇒ Object
4870 4871 4872 4873 4874 4875 4876 4877 4878 4879 4880 4881 4882 4883 4884 4885 4886 4887 4888 4889 4890 4891 4892 4893 4894 4895 4896 4897 4898 4899 4900 4901 4902 4903 4904 4905 4906 4907 4908 4909 4910 4911 4912 4913 4914 4915 4916 4917 4918 4919 4920 4921 4922 4923 4924 4925 4926 4927 4928 4929 4930 4931 4932 4933 4934 4935 4936 4937 4938 4939 4940 4941 4942 4943 4944 4945 4946 4947 4948 4949 4950 4951 4952 4953 4954 4955 4956 4957 4958 4959 4960 4961 4962 4963 4964 4965 4966 4967 4968 4969 4970 4971 4972 |
# File 'io.c', line 4870
static VALUE
rb_io_each_codepoint(VALUE io)
{
rb_io_t *fptr;
rb_encoding *enc;
unsigned int c;
int r, n;
RETURN_ENUMERATOR(io, 0, 0);
GetOpenFile(io, fptr);
rb_io_check_char_readable(fptr);
READ_CHECK(fptr);
if (NEED_READCONV(fptr)) {
SET_BINARY_MODE(fptr);
r = 1; /* no invalid char yet */
for (;;) {
make_readconv(fptr, 0);
for (;;) {
if (fptr->cbuf.len) {
if (fptr->encs.enc)
r = rb_enc_precise_mbclen(fptr->cbuf.ptr+fptr->cbuf.off,
fptr->cbuf.ptr+fptr->cbuf.off+fptr->cbuf.len,
fptr->encs.enc);
else
r = ONIGENC_CONSTRUCT_MBCLEN_CHARFOUND(1);
if (!MBCLEN_NEEDMORE_P(r))
break;
if (fptr->cbuf.len == fptr->cbuf.capa) {
rb_raise(rb_eIOError, "too long character");
}
}
if (more_char(fptr) == MORE_CHAR_FINISHED) {
clear_readconv(fptr);
if (!MBCLEN_CHARFOUND_P(r)) {
enc = fptr->encs.enc;
goto invalid;
}
return io;
}
}
if (MBCLEN_INVALID_P(r)) {
enc = fptr->encs.enc;
goto invalid;
}
n = MBCLEN_CHARFOUND_LEN(r);
if (fptr->encs.enc) {
c = rb_enc_codepoint(fptr->cbuf.ptr+fptr->cbuf.off,
fptr->cbuf.ptr+fptr->cbuf.off+fptr->cbuf.len,
fptr->encs.enc);
}
else {
c = (unsigned char)fptr->cbuf.ptr[fptr->cbuf.off];
}
fptr->cbuf.off += n;
fptr->cbuf.len -= n;
rb_yield(UINT2NUM(c));
rb_io_check_byte_readable(fptr);
}
}
NEED_NEWLINE_DECORATOR_ON_READ_CHECK(fptr);
enc = io_input_encoding(fptr);
while (io_fillbuf(fptr) >= 0) {
r = rb_enc_precise_mbclen(fptr->rbuf.ptr+fptr->rbuf.off,
fptr->rbuf.ptr+fptr->rbuf.off+fptr->rbuf.len, enc);
if (MBCLEN_CHARFOUND_P(r) &&
(n = MBCLEN_CHARFOUND_LEN(r)) <= fptr->rbuf.len) {
c = rb_enc_codepoint(fptr->rbuf.ptr+fptr->rbuf.off,
fptr->rbuf.ptr+fptr->rbuf.off+fptr->rbuf.len, enc);
fptr->rbuf.off += n;
fptr->rbuf.len -= n;
rb_yield(UINT2NUM(c));
}
else if (MBCLEN_INVALID_P(r)) {
goto invalid;
}
else if (MBCLEN_NEEDMORE_P(r)) {
char cbuf[8], *p = cbuf;
int more = MBCLEN_NEEDMORE_LEN(r);
if (more > numberof(cbuf)) goto invalid;
more += n = fptr->rbuf.len;
if (more > numberof(cbuf)) goto invalid;
while ((n = (int)read_buffered_data(p, more, fptr)) > 0 &&
(p += n, (more -= n) > 0)) {
if (io_fillbuf(fptr) < 0) goto invalid;
if ((n = fptr->rbuf.len) > more) n = more;
}
r = rb_enc_precise_mbclen(cbuf, p, enc);
if (!MBCLEN_CHARFOUND_P(r)) goto invalid;
c = rb_enc_codepoint(cbuf, p, enc);
rb_yield(UINT2NUM(c));
}
else {
continue;
}
rb_io_check_byte_readable(fptr);
}
return io;
invalid:
rb_raise(rb_eArgError, "invalid byte sequence in %s", rb_enc_name(enc));
UNREACHABLE_RETURN(Qundef);
}
|
#each_line(sep = $/, chomp: false) {|line| ... } ⇒ self #each_line(limit, chomp: false) {|line| ... } ⇒ self #each_line(sep, limit, chomp: false) {|line| ... } ⇒ self #each_line ⇒ Object
Calls the block with each remaining line read from the stream; returns self
. Does nothing if already at end-of-stream; See Line IO.
With no arguments given, reads lines as determined by line separator $/
:
f = File.new('t.txt')
f.each_line {|line| p line }
f.each_line {|line| fail 'Cannot happen' }
f.close
Output:
"First line\n"
"Second line\n"
"\n"
"Fourth line\n"
"Fifth line\n"
With only string argument sep
given, reads lines as determined by line separator sep
; see Line Separator:
f = File.new('t.txt')
f.each_line('li') {|line| p line }
f.close
Output:
"First li"
"ne\nSecond li"
"ne\n\nFourth li"
"ne\nFifth li"
"ne\n"
The two special values for sep
are honored:
f = File.new('t.txt')
# Get all into one string.
f.each_line(nil) {|line| p line }
f.close
Output:
"First line\nSecond line\n\nFourth line\nFifth line\n"
f.rewind
# Get paragraphs (up to two line separators).
f.each_line('') {|line| p line }
Output:
"First line\nSecond line\n\n"
"Fourth line\nFifth line\n"
With only integer argument limit
given, limits the number of bytes in each line; see Line Limit:
f = File.new('t.txt')
f.each_line(8) {|line| p line }
f.close
Output:
"First li"
"ne\n"
"Second l"
"ine\n"
"\n"
"Fourth l"
"ine\n"
"Fifth li"
"ne\n"
With arguments sep
and limit
given, combines the two behaviors:
-
Calls with the next line as determined by line separator
sep
. -
But returns no more bytes than are allowed by the limit.
Optional keyword argument chomp
specifies whether line separators are to be omitted:
f = File.new('t.txt')
f.each_line(chomp: true) {|line| p line }
f.close
Output:
"First line"
"Second line"
""
"Fourth line"
"Fifth line"
Returns an Enumerator if no block is given.
4648 4649 4650 4651 4652 4653 4654 4655 4656 4657 4658 4659 4660 4661 4662 |
# File 'io.c', line 4648
static VALUE
rb_io_each_line(int argc, VALUE *argv, VALUE io)
{
VALUE str;
struct getline_arg args;
RETURN_ENUMERATOR(io, argc, argv);
prepare_getline_args(argc, argv, &args, io);
if (args.limit == 0)
rb_raise(rb_eArgError, "invalid limit: 0 for each_line");
while (!NIL_P(str = rb_io_getline_1(args.rs, args.limit, args.chomp, io))) {
rb_yield(str);
}
return io;
}
|
#eof ⇒ Boolean
Returns true
if the stream is positioned at its end, false
otherwise; see Position:
f = File.open('t.txt')
f.eof # => false
f.seek(0, :END) # => 0
f.eof # => true
f.close
Raises an exception unless the stream is opened for reading; see Mode.
If self
is a stream such as pipe or socket, this method blocks until the other end sends some data or closes it:
r, w = IO.pipe
Thread.new { sleep 1; w.close }
r.eof? # => true # After 1-second wait.
r, w = IO.pipe
Thread.new { sleep 1; w.puts "a" }
r.eof? # => false # After 1-second wait.
r, w = IO.pipe
r.eof? # blocks forever
Note that this method reads data to the input byte buffer. So IO#sysread may not behave as you intend with IO#eof?, unless you call IO#rewind first (which is not available for some streams).
2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 |
# File 'io.c', line 2667
VALUE
rb_io_eof(VALUE io)
{
rb_io_t *fptr;
GetOpenFile(io, fptr);
rb_io_check_char_readable(fptr);
if (READ_CHAR_PENDING(fptr)) return Qfalse;
if (READ_DATA_PENDING(fptr)) return Qfalse;
READ_CHECK(fptr);
#if RUBY_CRLF_ENVIRONMENT
if (!NEED_READCONV(fptr) && NEED_NEWLINE_DECORATOR_ON_READ(fptr)) {
return RBOOL(eof(fptr->fd));;
}
#endif
return RBOOL(io_fillbuf(fptr) < 0);
}
|
#eof ⇒ Boolean
Returns true
if the stream is positioned at its end, false
otherwise; see Position:
f = File.open('t.txt')
f.eof # => false
f.seek(0, :END) # => 0
f.eof # => true
f.close
Raises an exception unless the stream is opened for reading; see Mode.
If self
is a stream such as pipe or socket, this method blocks until the other end sends some data or closes it:
r, w = IO.pipe
Thread.new { sleep 1; w.close }
r.eof? # => true # After 1-second wait.
r, w = IO.pipe
Thread.new { sleep 1; w.puts "a" }
r.eof? # => false # After 1-second wait.
r, w = IO.pipe
r.eof? # blocks forever
Note that this method reads data to the input byte buffer. So IO#sysread may not behave as you intend with IO#eof?, unless you call IO#rewind first (which is not available for some streams).
2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 |
# File 'io.c', line 2667
VALUE
rb_io_eof(VALUE io)
{
rb_io_t *fptr;
GetOpenFile(io, fptr);
rb_io_check_char_readable(fptr);
if (READ_CHAR_PENDING(fptr)) return Qfalse;
if (READ_DATA_PENDING(fptr)) return Qfalse;
READ_CHECK(fptr);
#if RUBY_CRLF_ENVIRONMENT
if (!NEED_READCONV(fptr) && NEED_NEWLINE_DECORATOR_ON_READ(fptr)) {
return RBOOL(eof(fptr->fd));;
}
#endif
return RBOOL(io_fillbuf(fptr) < 0);
}
|
#external_encoding ⇒ Encoding?
Returns the Encoding object that represents the encoding of the stream, or nil
if the stream is in write mode and no encoding is specified.
See Encodings.
13406 13407 13408 13409 13410 13411 13412 13413 13414 13415 13416 13417 13418 13419 13420 |
# File 'io.c', line 13406
static VALUE
rb_io_external_encoding(VALUE io)
{
rb_io_t *fptr = RFILE(rb_io_taint_check(io))->fptr;
if (fptr->encs.enc2) {
return rb_enc_from_encoding(fptr->encs.enc2);
}
if (fptr->mode & FMODE_WRITABLE) {
if (fptr->encs.enc)
return rb_enc_from_encoding(fptr->encs.enc);
return Qnil;
}
return rb_enc_from_encoding(io_read_encoding(fptr));
}
|
#fcntl(integer_cmd, argument) ⇒ Integer
Invokes Posix system call fcntl(2), which provides a mechanism for issuing low-level commands to control or query a file-oriented I/O stream. Arguments and results are platform dependent.
If argument
is a number, its value is passed directly; if it is a string, it is interpreted as a binary sequence of bytes. (Array#pack might be a useful way to build this string.)
Not implemented on all platforms.
11508 11509 11510 11511 11512 11513 11514 11515 |
# File 'io.c', line 11508
static VALUE
rb_io_fcntl(int argc, VALUE *argv, VALUE io)
{
VALUE req, arg;
rb_scan_args(argc, argv, "11", &req, &arg);
return rb_fcntl(io, req, arg);
}
|
#fdatasync ⇒ 0
Immediately writes to disk all data buffered in the stream, via the operating system’s: fdatasync(2)
, if supported, otherwise via fsync(2)
, if supported; otherwise raises an exception.
2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 |
# File 'io.c', line 2822
static VALUE
rb_io_fdatasync(VALUE io)
{
rb_io_t *fptr;
io = GetWriteIO(io);
GetOpenFile(io, fptr);
if (io_fflush(fptr) < 0)
rb_sys_fail_on_write(fptr);
if ((int)rb_thread_io_blocking_region(nogvl_fdatasync, fptr, fptr->fd) == 0)
return INT2FIX(0);
/* fall back */
return rb_io_fsync(io);
}
|
#fileno ⇒ Integer Also known as: to_i
2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 |
# File 'io.c', line 2857
static VALUE
rb_io_fileno(VALUE io)
{
rb_io_t *fptr = RFILE(io)->fptr;
int fd;
rb_io_check_closed(fptr);
fd = fptr->fd;
return INT2FIX(fd);
}
|
#flush ⇒ self
Flushes data buffered in self
to the operating system (but does not necessarily flush data buffered in the operating system):
$stdout.print 'no newline' # Not necessarily flushed.
$stdout.flush # Flushed.
2378 2379 2380 2381 2382 |
# File 'io.c', line 2378
VALUE
rb_io_flush(VALUE io)
{
return rb_io_flush_raw(io, 1);
}
|
#fsync ⇒ 0
Immediately writes to disk all data buffered in the stream, via the operating system’s fsync(2)
.
Note this difference:
-
IO#sync=: Ensures that data is flushed from the stream’s internal buffers, but does not guarantee that the operating system actually writes the data to disk.
-
IO#fsync: Ensures both that data is flushed from internal buffers, and that data is written to disk.
Raises an exception if the operating system does not support fsync(2)
.
2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 |
# File 'io.c', line 2773
static VALUE
rb_io_fsync(VALUE io)
{
rb_io_t *fptr;
io = GetWriteIO(io);
GetOpenFile(io, fptr);
if (io_fflush(fptr) < 0)
rb_sys_fail_on_write(fptr);
if ((int)rb_thread_io_blocking_region(nogvl_fsync, fptr, fptr->fd) < 0)
rb_sys_fail_path(fptr->pathv);
return INT2FIX(0);
}
|
#getbyte ⇒ Integer?
5055 5056 5057 5058 5059 5060 5061 5062 5063 5064 5065 5066 5067 5068 5069 5070 5071 5072 5073 5074 5075 5076 5077 5078 5079 |
# File 'io.c', line 5055
VALUE
rb_io_getbyte(VALUE io)
{
rb_io_t *fptr;
int c;
GetOpenFile(io, fptr);
rb_io_check_byte_readable(fptr);
READ_CHECK(fptr);
VALUE r_stdout = rb_ractor_stdout();
if (fptr->fd == 0 && (fptr->mode & FMODE_TTY) && RB_TYPE_P(r_stdout, T_FILE)) {
rb_io_t *ofp;
GetOpenFile(r_stdout, ofp);
if (ofp->mode & FMODE_TTY) {
rb_io_flush(r_stdout);
}
}
if (io_fillbuf(fptr) < 0) {
return Qnil;
}
fptr->rbuf.off++;
fptr->rbuf.len--;
c = (unsigned char)fptr->rbuf.ptr[fptr->rbuf.off-1];
return INT2FIX(c & 0xff);
}
|
#getc ⇒ nil
Reads and returns the next 1-character string from the stream; returns nil
if already at end-of-stream. See Character IO.
f = File.open('t.txt')
f.getc # => "F"
f.close
f = File.open('t.rus')
f.getc.ord # => 1090
f.close
Related: IO#readchar (may raise EOFError).
4993 4994 4995 4996 4997 4998 4999 5000 5001 5002 5003 5004 5005 |
# File 'io.c', line 4993
static VALUE
rb_io_getc(VALUE io)
{
rb_io_t *fptr;
rb_encoding *enc;
GetOpenFile(io, fptr);
rb_io_check_char_readable(fptr);
enc = io_input_encoding(fptr);
READ_CHECK(fptr);
return io_getc(fptr, enc);
}
|
#gets(sep = $/, chomp: false) ⇒ String? #gets(limit, chomp: false) ⇒ String? #gets(sep, limit, chomp: false) ⇒ String?
Reads and returns a line from the stream; assigns the return value to $_
. See Line IO.
With no arguments given, returns the next line as determined by line separator $/
, or nil
if none:
f = File.open('t.txt')
f.gets # => "First line\n"
$_ # => "First line\n"
f.gets # => "\n"
f.gets # => "Fourth line\n"
f.gets # => "Fifth line\n"
f.gets # => nil
f.close
With only string argument sep
given, returns the next line as determined by line separator sep
, or nil
if none; see Line Separator:
f = File.new('t.txt')
f.gets('l') # => "First l"
f.gets('li') # => "ine\nSecond li"
f.gets('lin') # => "ne\n\nFourth lin"
f.gets # => "e\n"
f.close
The two special values for sep
are honored:
f = File.new('t.txt')
# Get all.
f.gets(nil) # => "First line\nSecond line\n\nFourth line\nFifth line\n"
f.rewind
# Get paragraph (up to two line separators).
f.gets('') # => "First line\nSecond line\n\n"
f.close
With only integer argument limit
given, limits the number of bytes in the line; see Line Limit:
# No more than one line.
File.open('t.txt') {|f| f.gets(10) } # => "First line"
File.open('t.txt') {|f| f.gets(11) } # => "First line\n"
File.open('t.txt') {|f| f.gets(12) } # => "First line\n"
With arguments sep
and limit
given, combines the two behaviors:
-
Returns the next line as determined by line separator
sep
, ornil
if none. -
But returns no more bytes than are allowed by the limit.
Optional keyword argument chomp
specifies whether line separators are to be omitted:
f = File.open('t.txt')
# Chomp the lines.
f.gets(chomp: true) # => "First line"
f.gets(chomp: true) # => "Second line"
f.gets(chomp: true) # => ""
f.gets(chomp: true) # => "Fourth line"
f.gets(chomp: true) # => "Fifth line"
f.gets(chomp: true) # => nil
f.close
4362 4363 4364 4365 4366 4367 4368 4369 4370 4371 |
# File 'io.c', line 4362
static VALUE
rb_io_gets_m(int argc, VALUE *argv, VALUE io)
{
VALUE str;
str = rb_io_getline(argc, argv, io);
rb_lastline_set(str);
return str;
}
|
#initialize_copy(io) ⇒ Object
:nodoc:
8534 8535 8536 8537 8538 8539 8540 8541 8542 8543 8544 8545 8546 8547 8548 8549 8550 8551 8552 8553 8554 8555 8556 8557 8558 8559 8560 8561 8562 8563 8564 8565 8566 8567 8568 8569 8570 8571 8572 8573 8574 8575 |
# File 'io.c', line 8534
static VALUE
rb_io_init_copy(VALUE dest, VALUE io)
{
rb_io_t *fptr, *orig;
int fd;
VALUE write_io;
rb_off_t pos;
io = rb_io_get_io(io);
if (!OBJ_INIT_COPY(dest, io)) return dest;
GetOpenFile(io, orig);
MakeOpenFile(dest, fptr);
rb_io_flush(io);
/* copy rb_io_t structure */
fptr->mode = orig->mode & ~FMODE_EXTERNAL;
fptr->encs = orig->encs;
fptr->pid = orig->pid;
fptr->lineno = orig->lineno;
fptr->timeout = orig->timeout;
if (!NIL_P(orig->pathv)) fptr->pathv = orig->pathv;
fptr_copy_finalizer(fptr, orig);
fd = ruby_dup(orig->fd);
fptr->fd = fd;
pos = io_tell(orig);
if (0 <= pos)
io_seek(fptr, pos, SEEK_SET);
if (fptr->mode & FMODE_BINMODE) {
rb_io_binmode(dest);
}
write_io = GetWriteIO(io);
if (io != write_io) {
write_io = rb_obj_dup(write_io);
fptr->tied_io_for_writing = write_io;
rb_ivar_set(dest, rb_intern("@tied_io_for_writing"), write_io);
}
return dest;
}
|
#inspect ⇒ String
2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 |
# File 'io.c', line 2965
static VALUE
rb_io_inspect(VALUE obj)
{
rb_io_t *fptr;
VALUE result;
static const char closed[] = " (closed)";
fptr = RFILE(obj)->fptr;
if (!fptr) return rb_any_to_s(obj);
result = rb_str_new_cstr("#<");
rb_str_append(result, rb_class_name(CLASS_OF(obj)));
rb_str_cat2(result, ":");
if (NIL_P(fptr->pathv)) {
if (fptr->fd < 0) {
rb_str_cat(result, closed+1, strlen(closed)-1);
}
else {
rb_str_catf(result, "fd %d", fptr->fd);
}
}
else {
rb_str_append(result, fptr->pathv);
if (fptr->fd < 0) {
rb_str_cat(result, closed, strlen(closed));
}
}
return rb_str_cat2(result, ">");
}
|
#internal_encoding ⇒ Encoding?
Returns the Encoding object that represents the encoding of the internal string, if conversion is specified, or nil
otherwise.
See Encodings.
13434 13435 13436 13437 13438 13439 13440 13441 |
# File 'io.c', line 13434
static VALUE
rb_io_internal_encoding(VALUE io)
{
rb_io_t *fptr = RFILE(rb_io_taint_check(io))->fptr;
if (!fptr->encs.enc2) return Qnil;
return rb_enc_from_encoding(io_read_encoding(fptr));
}
|
#ioctl(integer_cmd, argument) ⇒ Integer
Invokes Posix system call ioctl(2), which issues a low-level command to an I/O device.
Issues a low-level command to an I/O device. The arguments and returned value are platform-dependent. The effect of the call is platform-dependent.
If argument argument
is an integer, it is passed directly; if it is a string, it is interpreted as a binary sequence of bytes.
Not implemented on all platforms.
11420 11421 11422 11423 11424 11425 11426 11427 |
# File 'io.c', line 11420
static VALUE
rb_io_ioctl(int argc, VALUE *argv, VALUE io)
{
VALUE req, arg;
rb_scan_args(argc, argv, "11", &req, &arg);
return rb_ioctl(io, req, arg);
}
|
#isatty ⇒ Boolean
5271 5272 5273 5274 5275 5276 5277 5278 |
# File 'io.c', line 5271
static VALUE
rb_io_isatty(VALUE io)
{
rb_io_t *fptr;
GetOpenFile(io, fptr);
return RBOOL(isatty(fptr->fd) != 0);
}
|
#lineno ⇒ Integer
Returns the current line number for the stream; see Line Number.
4382 4383 4384 4385 4386 4387 4388 4389 4390 |
# File 'io.c', line 4382
static VALUE
rb_io_lineno(VALUE io)
{
rb_io_t *fptr;
GetOpenFile(io, fptr);
rb_io_check_char_readable(fptr);
return INT2NUM(fptr->lineno);
}
|
#lineno=(integer) ⇒ Integer
Sets and returns the line number for the stream; see Line Number.
4401 4402 4403 4404 4405 4406 4407 4408 4409 4410 |
# File 'io.c', line 4401
static VALUE
rb_io_set_lineno(VALUE io, VALUE lineno)
{
rb_io_t *fptr;
GetOpenFile(io, fptr);
rb_io_check_char_readable(fptr);
fptr->lineno = NUM2INT(lineno);
return lineno;
}
|
#path ⇒ String?
2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 |
# File 'io.c', line 2942
VALUE
rb_io_path(VALUE io)
{
rb_io_t *fptr = RFILE(io)->fptr;
if (!fptr)
return Qnil;
return rb_obj_dup(fptr->pathv);
}
|
#pid ⇒ Integer?
Returns the process ID of a child process associated with the stream, which will have been set by IO#popen, or nil
if the stream was not created by IO#popen:
pipe = IO.popen("-")
if pipe
$stderr.puts "In parent, child pid is #{pipe.pid}"
else
$stderr.puts "In child, pid is #{$$}"
end
Output:
In child, pid is 26209
In parent, child pid is 26209
2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 |
# File 'io.c', line 2918
static VALUE
rb_io_pid(VALUE io)
{
rb_io_t *fptr;
GetOpenFile(io, fptr);
if (!fptr->pid)
return Qnil;
return PIDT2NUM(fptr->pid);
}
|
#tell ⇒ Integer
2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 |
# File 'io.c', line 2400
static VALUE
rb_io_tell(VALUE io)
{
rb_io_t *fptr;
rb_off_t pos;
GetOpenFile(io, fptr);
pos = io_tell(fptr);
if (pos < 0 && errno) rb_sys_fail_path(fptr->pathv);
pos -= fptr->rbuf.len;
return OFFT2NUM(pos);
}
|
#pos=(new_position) ⇒ Object
2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 |
# File 'io.c', line 2524
static VALUE
rb_io_set_pos(VALUE io, VALUE offset)
{
rb_io_t *fptr;
rb_off_t pos;
pos = NUM2OFFT(offset);
GetOpenFile(io, fptr);
pos = io_seek(fptr, pos, SEEK_SET);
if (pos < 0 && errno) rb_sys_fail_path(fptr->pathv);
return OFFT2NUM(pos);
}
|
#pread(maxlen, offset) ⇒ String #pread(maxlen, offset, out_string) ⇒ String
Behaves like IO#readpartial, except that it:
-
Reads at the given
offset
(in bytes). -
Disregards, and does not modify, the stream’s position (see Position).
-
Bypasses any user space buffering in the stream.
Because this method does not disturb the stream’s state (its position, in particular), pread
allows multiple threads and processes to use the same IO object for reading at various offsets.
f = File.open('t.txt')
f.read # => "First line\nSecond line\n\nFourth line\nFifth line\n"
f.pos # => 52
# Read 12 bytes at offset 0.
f.pread(12, 0) # => "First line\n"
# Read 9 bytes at offset 8.
f.pread(9, 8) # => "ne\nSecon"
f.close
Not available on some platforms.
6201 6202 6203 6204 6205 6206 6207 6208 6209 6210 6211 6212 6213 6214 6215 6216 6217 6218 6219 6220 6221 6222 6223 6224 6225 6226 6227 6228 6229 6230 6231 6232 6233 6234 6235 6236 |
# File 'io.c', line 6201
static VALUE
rb_io_pread(int argc, VALUE *argv, VALUE io)
{
VALUE len, offset, str;
rb_io_t *fptr;
ssize_t n;
struct prdwr_internal_arg arg = {.io = io};
int shrinkable;
rb_scan_args(argc, argv, "21", &len, &offset, &str);
arg.count = NUM2SIZET(len);
arg.offset = NUM2OFFT(offset);
shrinkable = io_setstrbuf(&str, (long)arg.count);
if (arg.count == 0) return str;
arg.buf = RSTRING_PTR(str);
GetOpenFile(io, fptr);
rb_io_check_byte_readable(fptr);
arg.fd = fptr->fd;
rb_io_check_closed(fptr);
rb_str_locktmp(str);
n = (ssize_t)rb_ensure(pread_internal_call, (VALUE)&arg, rb_str_unlocktmp, str);
if (n < 0) {
rb_sys_fail_path(fptr->pathv);
}
io_set_read_length(str, n, shrinkable);
if (n == 0 && arg.count > 0) {
rb_eof_error();
}
return str;
}
|
#print(*objects) ⇒ nil
Writes the given objects to the stream; returns nil
. Appends the output record separator $OUTPUT_RECORD_SEPARATOR
($\
), if it is not nil
. See Line IO.
With argument objects
given, for each object:
-
Converts via its method
to_s
if not a string. -
Writes to the stream.
-
If not the last object, writes the output field separator
$OUTPUT_FIELD_SEPARATOR
($,
) if it is notnil
.
With default separators:
f = File.open('t.tmp', 'w+')
objects = [0, 0.0, Rational(0, 1), Complex(0, 0), :zero, 'zero']
p $OUTPUT_RECORD_SEPARATOR
p $OUTPUT_FIELD_SEPARATOR
f.print(*objects)
f.rewind
p f.read
f.close
Output:
nil
nil
"00.00/10+0izerozero"
With specified separators:
$\ = "\n"
$, = ','
f.rewind
f.print(*objects)
f.rewind
p f.read
Output:
"0,0.0,0/1,0+0i,zero,zero\n"
With no argument given, writes the content of $_
(which is usually the most recent user input):
f = File.open('t.tmp', 'w+')
gets # Sets $_ to the most recent user input.
f.print
f.close
8714 8715 8716 8717 8718 8719 8720 8721 8722 8723 8724 8725 8726 8727 8728 8729 8730 8731 8732 8733 8734 8735 8736 8737 8738 8739 8740 |
# File 'io.c', line 8714
VALUE
rb_io_print(int argc, const VALUE *argv, VALUE out)
{
int i;
VALUE line;
/* if no argument given, print `$_' */
if (argc == 0) {
argc = 1;
line = rb_lastline_get();
argv = &line;
}
if (argc > 1 && !NIL_P(rb_output_fs)) {
rb_category_warn(RB_WARN_CATEGORY_DEPRECATED, "$, is set to non-nil value");
}
for (i=0; i<argc; i++) {
if (!NIL_P(rb_output_fs) && i>0) {
rb_io_write(out, rb_output_fs);
}
rb_io_write(out, argv[i]);
}
if (argc > 0 && !NIL_P(rb_output_rs)) {
rb_io_write(out, rb_output_rs);
}
return Qnil;
}
|
#printf(format_string, *objects) ⇒ nil
Formats and writes objects
to the stream.
For details on format_string
, see Format Specifications.
8588 8589 8590 8591 8592 8593 |
# File 'io.c', line 8588
VALUE
rb_io_printf(int argc, const VALUE *argv, VALUE out)
{
rb_io_write(out, rb_f_sprintf(argc, argv));
return Qnil;
}
|
#putc(object) ⇒ Object
Writes a character to the stream. See Character IO.
If object
is numeric, converts to integer if necessary, then writes the character whose code is the least significant byte; if object
is a string, writes the first character:
$stdout.putc "A"
$stdout.putc 65
Output:
AA
8819 8820 8821 8822 8823 8824 8825 8826 8827 8828 8829 8830 8831 8832 |
# File 'io.c', line 8819
static VALUE
rb_io_putc(VALUE io, VALUE ch)
{
VALUE str;
if (RB_TYPE_P(ch, T_STRING)) {
str = rb_str_substr(ch, 0, 1);
}
else {
char c = NUM2CHR(ch);
str = rb_str_new(&c, 1);
}
rb_io_write(io, str);
return ch;
}
|
#puts(*objects) ⇒ nil
Writes the given objects
to the stream, which must be open for writing; returns nil
.\ Writes a newline after each that does not already end with a newline sequence. If called without arguments, writes a newline. See Line IO.
Note that each added newline is the character "\n"<//tt>, not the output record separator (<tt>$\
).
Treatment for each object:
-
String: writes the string.
-
Neither string nor array: writes
object.to_s
. -
Array: writes each element of the array; arrays may be nested.
To keep these examples brief, we define this helper method:
def show(*objects)
# Puts objects to file.
f = File.new('t.tmp', 'w+')
f.puts(objects)
# Return file content.
f.rewind
p f.read
f.close
end
# Strings without newlines.
show('foo', 'bar', 'baz') # => "foo\nbar\nbaz\n"
# Strings, some with newlines.
show("foo\n", 'bar', "baz\n") # => "foo\nbar\nbaz\n"
# Neither strings nor arrays:
show(0, 0.0, Rational(0, 1), Complex(9, 0), :zero)
# => "0\n0.0\n0/1\n9+0i\nzero\n"
# Array of strings.
show(['foo', "bar\n", 'baz']) # => "foo\nbar\nbaz\n"
# Nested arrays.
show([[[0, 1], 2, 3], 4, 5]) # => "0\n1\n2\n3\n4\n5\n"
8946 8947 8948 8949 8950 8951 8952 8953 8954 8955 8956 8957 8958 8959 8960 8961 8962 8963 8964 8965 8966 8967 8968 8969 8970 8971 8972 8973 8974 8975 8976 8977 8978 8979 8980 8981 8982 8983 8984 |
# File 'io.c', line 8946
VALUE
rb_io_puts(int argc, const VALUE *argv, VALUE out)
{
VALUE line, args[2];
/* if no argument given, print newline. */
if (argc == 0) {
rb_io_write(out, rb_default_rs);
return Qnil;
}
for (int i = 0; i < argc; i++) {
// Convert the argument to a string:
if (RB_TYPE_P(argv[i], T_STRING)) {
line = argv[i];
}
else if (rb_exec_recursive(io_puts_ary, argv[i], out)) {
continue;
}
else {
line = rb_obj_as_string(argv[i]);
}
// Write the line:
int n = 0;
if (RSTRING_LEN(line) == 0) {
args[n++] = rb_default_rs;
}
else {
args[n++] = line;
if (!rb_str_end_with_asciichar(line, '\n')) {
args[n++] = rb_default_rs;
}
}
rb_io_writev(out, n, args);
}
return Qnil;
}
|
#pwrite(object, offset) ⇒ Integer
Behaves like IO#write, except that it:
-
Writes at the given
offset
(in bytes). -
Disregards, and does not modify, the stream’s position (see Position).
-
Bypasses any user space buffering in the stream.
Because this method does not disturb the stream’s state (its position, in particular), pwrite
allows multiple threads and processes to use the same IO object for writing at various offsets.
f = File.open('t.tmp', 'w+')
# Write 6 bytes at offset 3.
f.pwrite('ABCDEF', 3) # => 6
f.rewind
f.read # => "\u0000\u0000\u0000ABCDEF"
f.close
Not available on some platforms.
6281 6282 6283 6284 6285 6286 6287 6288 6289 6290 6291 6292 6293 6294 6295 6296 6297 6298 6299 6300 6301 6302 6303 6304 6305 6306 6307 6308 |
# File 'io.c', line 6281
static VALUE
rb_io_pwrite(VALUE io, VALUE str, VALUE offset)
{
rb_io_t *fptr;
ssize_t n;
struct prdwr_internal_arg arg = {.io = io};
VALUE tmp;
if (!RB_TYPE_P(str, T_STRING))
str = rb_obj_as_string(str);
arg.offset = NUM2OFFT(offset);
io = GetWriteIO(io);
GetOpenFile(io, fptr);
rb_io_check_writable(fptr);
arg.fd = fptr->fd;
tmp = rb_str_tmp_frozen_acquire(str);
arg.buf = RSTRING_PTR(tmp);
arg.count = (size_t)RSTRING_LEN(tmp);
n = (ssize_t)rb_thread_io_blocking_call(internal_pwrite_func, &arg, fptr->fd, RB_WAITFD_OUT);
if (n < 0) rb_sys_fail_path(fptr->pathv);
rb_str_tmp_frozen_release(str, tmp);
return SSIZET2NUM(n);
}
|
#read(maxlen = nil, out_string = nil) ⇒ nil
Reads bytes from the stream; the stream must be opened for reading (see Access Modes):
-
If
maxlen
isnil
, reads all bytes using the stream’s data mode. -
Otherwise reads up to
maxlen
bytes in binary mode.
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
:
-
maxlen
isnil
: uses internal encoding ofself
(regardless of whetherout_string
was given). -
maxlen
notnil
:-
out_string
given: encoding ofout_string
not modified. -
out_string
not 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
# => "First line\nSecond line\n\nFourth line\nFifth line\n"
f.rewind
f.read(30) # => "First line\r\nSecond line\r\n\r\nFou"
f.read(30) # => "rth line\r\nFifth line\r\n"
f.read(30) # => nil
f.close
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) # => "First line\nSecond line\n\nFourth line\nFifth line\n"
s # => "First line\nSecond line\n\nFourth line\nFifth line\n"
f.rewind
s = 'bar'
f.read(30, s) # => "First line\r\nSecond line\r\n\r\nFou"
s # => "First line\r\nSecond line\r\n\r\nFou"
s = 'baz'
f.read(30, s) # => "rth line\r\nFifth line\r\n"
s # => "rth line\r\nFifth line\r\n"
s = 'bat'
f.read(30, s) # => nil
s # => ""
f.close
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.
Related: IO#write.
3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 |
# File 'io.c', line 3773
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;
}
|
#readbyte ⇒ Integer
5100 5101 5102 5103 5104 5105 5106 5107 5108 5109 |
# File 'io.c', line 5100
static VALUE
rb_io_readbyte(VALUE io)
{
VALUE c = rb_io_getbyte(io);
if (NIL_P(c)) {
rb_eof_error();
}
return c;
}
|
#readchar ⇒ String
Reads and returns the next 1-character string from the stream; raises EOFError if already at end-of-stream. See Character IO.
f = File.open('t.txt')
f.readchar # => "F"
f.close
f = File.open('t.rus')
f.readchar.ord # => 1090
f.close
Related: IO#getc (will not raise EOFError).
5026 5027 5028 5029 5030 5031 5032 5033 5034 5035 |
# File 'io.c', line 5026
static VALUE
rb_io_readchar(VALUE io)
{
VALUE c = rb_io_getc(io);
if (NIL_P(c)) {
rb_eof_error();
}
return c;
}
|
#readlines(sep = $/, chomp: false) ⇒ Array #readlines(limit, chomp: false) ⇒ Array #readlines(sep, limit, chomp: false) ⇒ Array
Reads and returns all remaining line from the stream; does not modify $_
. See Line IO.
With no arguments given, returns lines as determined by line separator $/
, or nil
if none:
f = File.new('t.txt')
f.readlines
# => ["First line\n", "Second line\n", "\n", "Fourth line\n", "Fifth line\n"]
f.readlines # => []
f.close
With only string argument sep
given, returns lines as determined by line separator sep
, or nil
if none; see Line Separator:
f = File.new('t.txt')
f.readlines('li')
# => ["First li", "ne\nSecond li", "ne\n\nFourth li", "ne\nFifth li", "ne\n"]
f.close
The two special values for sep
are honored:
f = File.new('t.txt')
# Get all into one string.
f.readlines(nil)
# => ["First line\nSecond line\n\nFourth line\nFifth line\n"]
# Get paragraphs (up to two line separators).
f.rewind
f.readlines('')
# => ["First line\nSecond line\n\n", "Fourth line\nFifth line\n"]
f.close
With only integer argument limit
given, limits the number of bytes in each line; see Line Limit:
f = File.new('t.txt')
f.readlines(8)
# => ["First li", "ne\n", "Second l", "ine\n", "\n", "Fourth l", "ine\n", "Fifth li", "ne\n"]
f.close
With arguments sep
and limit
given, combines the two behaviors:
-
Returns lines as determined by line separator
sep
. -
But returns no more bytes in a line than are allowed by the limit.
Optional keyword argument chomp
specifies whether line separators are to be omitted:
f = File.new('t.txt')
f.readlines(chomp: true)
# => ["First line", "Second line", "", "Fourth line", "Fifth line"]
f.close
4517 4518 4519 4520 4521 4522 4523 4524 |
# File 'io.c', line 4517
static VALUE
rb_io_readlines(int argc, VALUE *argv, VALUE io)
{
struct getline_arg args;
prepare_getline_args(argc, argv, &args, io);
return io_readlines(&args, io);
}
|
#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_string
is given. -
ASCII-8BIT, otherwise.
-
Contains
maxlen
bytes 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" "" ""
3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 |
# File 'io.c', line 3589
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;
}
|
#reopen(other_io) ⇒ self #reopen(path, mode = 'r', **opts) ⇒ self
Reassociates the stream with another stream, which may be of a different class. This method may be used to redirect an existing stream to a new destination.
With argument other_io
given, reassociates with that stream:
# Redirect $stdin from a file.
f = File.open('t.txt')
$stdin.reopen(f)
f.close
# Redirect $stdout to a file.
f = File.open('t.tmp', 'w')
$stdout.reopen(f)
f.close
With argument path
given, reassociates with a new stream to that file path:
$stdin.reopen('t.txt')
$stdout.reopen('t.tmp', 'w')
Optional keyword arguments opts
specify:
8445 8446 8447 8448 8449 8450 8451 8452 8453 8454 8455 8456 8457 8458 8459 8460 8461 8462 8463 8464 8465 8466 8467 8468 8469 8470 8471 8472 8473 8474 8475 8476 8477 8478 8479 8480 8481 8482 8483 8484 8485 8486 8487 8488 8489 8490 8491 8492 8493 8494 8495 8496 8497 8498 8499 8500 8501 8502 8503 8504 8505 8506 8507 8508 8509 8510 8511 8512 8513 8514 8515 8516 8517 8518 8519 8520 8521 8522 8523 8524 8525 8526 8527 8528 8529 8530 8531 |
# File 'io.c', line 8445
static VALUE
rb_io_reopen(int argc, VALUE *argv, VALUE file)
{
VALUE fname, nmode, opt;
int oflags;
rb_io_t *fptr;
if (rb_scan_args(argc, argv, "11:", &fname, &nmode, &opt) == 1) {
VALUE tmp = rb_io_check_io(fname);
if (!NIL_P(tmp)) {
return io_reopen(file, tmp);
}
}
FilePathValue(fname);
rb_io_taint_check(file);
fptr = RFILE(file)->fptr;
if (!fptr) {
fptr = RFILE(file)->fptr = ZALLOC(rb_io_t);
}
if (!NIL_P(nmode) || !NIL_P(opt)) {
int fmode;
struct rb_io_encoding convconfig;
rb_io_extract_modeenc(&nmode, 0, opt, &oflags, &fmode, &convconfig);
if (RUBY_IO_EXTERNAL_P(fptr) &&
((fptr->mode & FMODE_READWRITE) & (fmode & FMODE_READWRITE)) !=
(fptr->mode & FMODE_READWRITE)) {
rb_raise(rb_eArgError,
"%s can't change access mode from \"%s\" to \"%s\"",
PREP_STDIO_NAME(fptr), rb_io_fmode_modestr(fptr->mode),
rb_io_fmode_modestr(fmode));
}
fptr->mode = fmode;
fptr->encs = convconfig;
}
else {
oflags = rb_io_fmode_oflags(fptr->mode);
}
fptr->pathv = fname;
if (fptr->fd < 0) {
fptr->fd = rb_sysopen(fptr->pathv, oflags, 0666);
fptr->stdio_file = 0;
return file;
}
if (fptr->mode & FMODE_WRITABLE) {
if (io_fflush(fptr) < 0)
rb_sys_fail_on_write(fptr);
}
fptr->rbuf.off = fptr->rbuf.len = 0;
if (fptr->stdio_file) {
int e = rb_freopen(rb_str_encode_ospath(fptr->pathv),
rb_io_oflags_modestr(oflags),
fptr->stdio_file);
if (e) rb_syserr_fail_path(e, fptr->pathv);
fptr->fd = fileno(fptr->stdio_file);
rb_fd_fix_cloexec(fptr->fd);
#ifdef USE_SETVBUF
if (setvbuf(fptr->stdio_file, NULL, _IOFBF, 0) != 0)
rb_warn("setvbuf() can't be honoured for %"PRIsVALUE, fptr->pathv);
#endif
if (fptr->stdio_file == stderr) {
if (setvbuf(fptr->stdio_file, NULL, _IONBF, BUFSIZ) != 0)
rb_warn("setvbuf() can't be honoured for %"PRIsVALUE, fptr->pathv);
}
else if (fptr->stdio_file == stdout && isatty(fptr->fd)) {
if (setvbuf(fptr->stdio_file, NULL, _IOLBF, BUFSIZ) != 0)
rb_warn("setvbuf() can't be honoured for %"PRIsVALUE, fptr->pathv);
}
}
else {
int tmpfd = rb_sysopen(fptr->pathv, oflags, 0666);
int err = 0;
if (rb_cloexec_dup2(tmpfd, fptr->fd) < 0)
err = errno;
(void)close(tmpfd);
if (err) {
rb_syserr_fail_path(err, fptr->pathv);
}
}
return file;
}
|
#rewind ⇒ 0
Repositions the stream to its beginning, setting both the position and the line number to zero; see Position and Line Number:
f = File.open('t.txt')
f.tell # => 0
f.lineno # => 0
f.gets # => "First line\n"
f.tell # => 12
f.lineno # => 1
f.rewind # => 0
f.tell # => 0
f.lineno # => 0
f.close
Note that this method cannot be used with streams such as pipes, ttys, and sockets.
2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 |
# File 'io.c', line 2564
static VALUE
rb_io_rewind(VALUE io)
{
rb_io_t *fptr;
GetOpenFile(io, fptr);
if (io_seek(fptr, 0L, 0) < 0 && errno) rb_sys_fail_path(fptr->pathv);
if (io == ARGF.current_file) {
ARGF.lineno -= fptr->lineno;
}
fptr->lineno = 0;
if (fptr->readconv) {
clear_readconv(fptr);
}
return INT2FIX(0);
}
|
#seek(offset, whence = IO::SEEK_SET) ⇒ 0
Seeks to the position given by integer offset
(see Position) and constant whence
, which is one of:
-
:CUR
orIO::SEEK_CUR
: Repositions the stream to its current position plus the givenoffset
:f = File.open('t.txt') f.tell # => 0 f.seek(20, :CUR) # => 0 f.tell # => 20 f.seek(-10, :CUR) # => 0 f.tell # => 10 f.close
-
:END
orIO::SEEK_END
: Repositions the stream to its end plus the givenoffset
:f = File.open('t.txt') f.tell # => 0 f.seek(0, :END) # => 0 # Repositions to stream end. f.tell # => 52 f.seek(-20, :END) # => 0 f.tell # => 32 f.seek(-40, :END) # => 0 f.tell # => 12 f.close
-
:SET
orIO:SEEK_SET
: Repositions the stream to the givenoffset
:f = File.open('t.txt') f.tell # => 0 f.seek(20, :SET) # => 0 f.tell # => 20 f.seek(40, :SET) # => 0 f.tell # => 40 f.close
Related: IO#pos=, IO#tell.
2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 |
# File 'io.c', line 2494
static VALUE
rb_io_seek_m(int argc, VALUE *argv, VALUE io)
{
VALUE offset, ptrname;
int whence = SEEK_SET;
if (rb_scan_args(argc, argv, "11", &offset, &ptrname) == 2) {
whence = interpret_seek_whence(ptrname);
}
return rb_io_seek(io, offset, whence);
}
|
#set_encoding(ext_enc) ⇒ self #set_encoding(ext_enc, int_enc, **enc_opts) ⇒ self #set_encoding('ext_enc: int_enc', **enc_opts) ⇒ self
See Encodings.
Argument ext_enc
, if given, must be an Encoding object or a String with the encoding name; it is assigned as the encoding for the stream.
Argument int_enc
, if given, must be an Encoding object or a String with the encoding name; it is assigned as the encoding for the internal string.
Argument 'ext_enc:int_enc'
, if given, is a string containing two colon-separated encoding names; corresponding Encoding objects are assigned as the external and internal encodings for the stream.
If the external encoding of a string is binary/ASCII-8BIT, the internal encoding of the string is set to nil, since no transcoding is needed.
Optional keyword arguments enc_opts
specify Encoding options.
13473 13474 13475 13476 13477 13478 13479 13480 13481 13482 13483 13484 13485 13486 13487 |
# File 'io.c', line 13473
static VALUE
rb_io_set_encoding(int argc, VALUE *argv, VALUE io)
{
rb_io_t *fptr;
VALUE v1, v2, opt;
if (!RB_TYPE_P(io, T_FILE)) {
return forward(io, id_set_encoding, argc, argv);
}
argc = rb_scan_args(argc, argv, "11:", &v1, &v2, &opt);
GetOpenFile(io, fptr);
io_encoding_set(fptr, v1, v2, opt);
return io;
}
|
#set_encoding_by_bom ⇒ Encoding?
If the stream begins with a BOM (byte order marker), consumes the BOM and sets the external encoding accordingly; returns the result encoding if found, or nil
otherwise:
File.write('t.tmp', "\u{FEFF}abc")
io = File.open('t.tmp', 'rb')
io.set_encoding_by_bom # => #<Encoding:UTF-8>
io.close
File.write('t.tmp', 'abc')
io = File.open('t.tmp', 'rb')
io.set_encoding_by_bom # => nil
io.close
Raises an exception if the stream is not binmode or its encoding has already been set.
9554 9555 9556 9557 9558 9559 9560 9561 9562 9563 9564 9565 9566 9567 9568 9569 9570 9571 9572 |
# File 'io.c', line 9554
static VALUE
rb_io_set_encoding_by_bom(VALUE io)
{
rb_io_t *fptr;
GetOpenFile(io, fptr);
if (!(fptr->mode & FMODE_BINMODE)) {
rb_raise(rb_eArgError, "ASCII incompatible encoding needs binmode");
}
if (fptr->encs.enc2) {
rb_raise(rb_eArgError, "encoding conversion is set");
}
else if (fptr->encs.enc && fptr->encs.enc != rb_ascii8bit_encoding()) {
rb_raise(rb_eArgError, "encoding is set to %s already",
rb_enc_name(fptr->encs.enc));
}
if (!io_set_encoding_by_bom(io)) return Qnil;
return rb_enc_from_encoding(fptr->encs.enc);
}
|
#stat ⇒ Object
1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 |
# File 'file.c', line 1356
static VALUE
rb_io_stat(VALUE obj)
{
rb_io_t *fptr;
struct stat st;
GetOpenFile(obj, fptr);
if (fstat(fptr->fd, &st) == -1) {
rb_sys_fail_path(fptr->pathv);
}
return rb_stat_new(&st);
}
|
#sync ⇒ Boolean
2702 2703 2704 2705 2706 2707 2708 2709 2710 |
# File 'io.c', line 2702
static VALUE
rb_io_sync(VALUE io)
{
rb_io_t *fptr;
io = GetWriteIO(io);
GetOpenFile(io, fptr);
return RBOOL(fptr->mode & FMODE_SYNC);
}
|
#sync=(sync) ⇒ Object
2790 2791 2792 2793 2794 2795 |
# File 'io.c', line 2790
static VALUE
rb_io_set_sync(VALUE io, VALUE sync)
{
rb_notimplement();
UNREACHABLE;
}
|
#sysread(maxlen) ⇒ String #sysread(maxlen, out_string) ⇒ String
Behaves like IO#readpartial, except that it uses low-level system functions.
This method should not be used with other stream-reader methods.
6093 6094 6095 6096 6097 6098 6099 6100 6101 6102 6103 6104 6105 6106 6107 6108 6109 6110 6111 6112 6113 6114 6115 6116 6117 6118 6119 6120 6121 6122 6123 6124 6125 6126 6127 6128 6129 6130 6131 6132 6133 6134 6135 6136 6137 6138 |
# File 'io.c', line 6093
static VALUE
rb_io_sysread(int argc, VALUE *argv, VALUE io)
{
VALUE len, str;
rb_io_t *fptr;
long n, ilen;
struct io_internal_read_struct iis;
int shrinkable;
rb_scan_args(argc, argv, "11", &len, &str);
ilen = NUM2LONG(len);
shrinkable = io_setstrbuf(&str, ilen);
if (ilen == 0) return str;
GetOpenFile(io, fptr);
rb_io_check_byte_readable(fptr);
if (READ_DATA_BUFFERED(fptr)) {
rb_raise(rb_eIOError, "sysread for buffered IO");
}
rb_io_check_closed(fptr);
io_setstrbuf(&str, ilen);
iis.th = rb_thread_current();
iis.fptr = fptr;
iis.nonblock = 0;
iis.fd = fptr->fd;
iis.buf = RSTRING_PTR(str);
iis.capa = ilen;
iis.timeout = NULL;
n = io_read_memory_locktmp(str, &iis);
if (n < 0) {
rb_sys_fail_path(fptr->pathv);
}
io_set_read_length(str, n, shrinkable);
if (n == 0 && ilen > 0) {
rb_eof_error();
}
return str;
}
|
#sysseek(offset, whence = IO::SEEK_SET) ⇒ Integer
Behaves like IO#seek, except that it:
-
Uses low-level system functions.
-
Returns the new position.
6009 6010 6011 6012 6013 6014 6015 6016 6017 6018 6019 6020 6021 6022 6023 6024 6025 6026 6027 6028 6029 6030 6031 6032 6033 6034 |
# File 'io.c', line 6009
static VALUE
rb_io_sysseek(int argc, VALUE *argv, VALUE io)
{
VALUE offset, ptrname;
int whence = SEEK_SET;
rb_io_t *fptr;
rb_off_t pos;
if (rb_scan_args(argc, argv, "11", &offset, &ptrname) == 2) {
whence = interpret_seek_whence(ptrname);
}
pos = NUM2OFFT(offset);
GetOpenFile(io, fptr);
if ((fptr->mode & FMODE_READABLE) &&
(READ_DATA_BUFFERED(fptr) || READ_CHAR_PENDING(fptr))) {
rb_raise(rb_eIOError, "sysseek for buffered IO");
}
if ((fptr->mode & FMODE_WRITABLE) && fptr->wbuf.len) {
rb_warn("sysseek for buffered IO");
}
errno = 0;
pos = lseek(fptr->fd, pos, whence);
if (pos < 0 && errno) rb_sys_fail_path(fptr->pathv);
return OFFT2NUM(pos);
}
|
#syswrite(object) ⇒ Integer
Writes the given object
to self, which must be opened for writing (see Modes); returns the number bytes written. If object
is not a string is converted via method to_s:
f = File.new('t.tmp', 'w')
f.syswrite('foo') # => 3
f.syswrite(30) # => 2
f.syswrite(:foo) # => 3
f.close
This methods should not be used with other stream-writer methods.
6054 6055 6056 6057 6058 6059 6060 6061 6062 6063 6064 6065 6066 6067 6068 6069 6070 6071 6072 6073 6074 6075 6076 6077 6078 6079 6080 |
# File 'io.c', line 6054
static VALUE
rb_io_syswrite(VALUE io, VALUE str)
{
VALUE tmp;
rb_io_t *fptr;
long n, len;
const char *ptr;
if (!RB_TYPE_P(str, T_STRING))
str = rb_obj_as_string(str);
io = GetWriteIO(io);
GetOpenFile(io, fptr);
rb_io_check_writable(fptr);
if (fptr->wbuf.len) {
rb_warn("syswrite for buffered IO");
}
tmp = rb_str_tmp_frozen_acquire(str);
RSTRING_GETMEM(tmp, ptr, len);
n = rb_io_write_memory(fptr, ptr, len);
if (n < 0) rb_sys_fail_path(fptr->pathv);
rb_str_tmp_frozen_release(str, tmp);
return LONG2FIX(n);
}
|
#tell ⇒ Integer
2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 |
# File 'io.c', line 2400
static VALUE
rb_io_tell(VALUE io)
{
rb_io_t *fptr;
rb_off_t pos;
GetOpenFile(io, fptr);
pos = io_tell(fptr);
if (pos < 0 && errno) rb_sys_fail_path(fptr->pathv);
pos -= fptr->rbuf.len;
return OFFT2NUM(pos);
}
|
#timeout ⇒ nil
Get the internal timeout duration or nil if it was not set.
837 838 839 840 841 842 843 |
# File 'io.c', line 837
VALUE
rb_io_timeout(VALUE self)
{
rb_io_t *fptr = rb_io_get_fptr(self);
return fptr->timeout;
}
|
#timeout=(duration) ⇒ Object #timeout=(nil) ⇒ nil
Sets the internal timeout to the specified duration or nil. The timeout applies to all blocking operations where possible.
When the operation performs longer than the timeout set, IO::TimeoutError is raised.
This affects the following methods (but is not limited to): #gets, #puts, #read, #write, #wait_readable and #wait_writable. This also affects blocking socket operations like Socket#accept and Socket#connect.
Some operations like File#open and IO#close are not affected by the timeout. A timeout during a write operation may leave the IO in an inconsistent state, e.g. data was partially written. Generally speaking, a timeout is a last ditch effort to prevent an application from hanging on slow I/O operations, such as those that occur during a slowloris attack.
866 867 868 869 870 871 872 873 874 875 876 877 878 879 |
# File 'io.c', line 866
VALUE
rb_io_set_timeout(VALUE self, VALUE timeout)
{
// Validate it:
if (RTEST(timeout)) {
rb_time_interval(timeout);
}
rb_io_t *fptr = rb_io_get_fptr(self);
fptr->timeout = timeout;
return self;
}
|
#to_io ⇒ self
Returns self
.
3002 3003 3004 3005 3006 |
# File 'io.c', line 3002
static VALUE
rb_io_to_io(VALUE io)
{
return io;
}
|
#path ⇒ String?
2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 |
# File 'io.c', line 2942
VALUE
rb_io_path(VALUE io)
{
rb_io_t *fptr = RFILE(io)->fptr;
if (!fptr)
return Qnil;
return rb_obj_dup(fptr->pathv);
}
|
#isatty ⇒ Boolean
5271 5272 5273 5274 5275 5276 5277 5278 |
# File 'io.c', line 5271
static VALUE
rb_io_isatty(VALUE io)
{
rb_io_t *fptr;
GetOpenFile(io, fptr);
return RBOOL(isatty(fptr->fd) != 0);
}
|
#ungetbyte(integer) ⇒ nil #ungetbyte(string) ⇒ nil
Pushes back (“unshifts”) the given data onto the stream’s buffer, placing the data so that it is next to be read; returns nil
. See Byte IO.
Note that:
-
Calling the method has no effect with unbuffered reads (such as IO#sysread).
-
Calling #rewind on the stream discards the pushed-back data.
When argument integer
is given, uses only its low-order byte:
File.write('t.tmp', '012')
f = File.open('t.tmp')
f.ungetbyte(0x41) # => nil
f.read # => "A012"
f.rewind
f.ungetbyte(0x4243) # => nil
f.read # => "C012"
f.close
When argument string
is given, uses all bytes:
File.write('t.tmp', '012')
f = File.open('t.tmp')
f.ungetbyte('A') # => nil
f.read # => "A012"
f.rewind
f.ungetbyte('BCDE') # => nil
f.read # => "BCDE012"
f.close
5149 5150 5151 5152 5153 5154 5155 5156 5157 5158 5159 5160 5161 5162 5163 5164 5165 5166 5167 5168 5169 5170 |
# File 'io.c', line 5149
VALUE
rb_io_ungetbyte(VALUE io, VALUE b)
{
rb_io_t *fptr;
GetOpenFile(io, fptr);
rb_io_check_byte_readable(fptr);
switch (TYPE(b)) {
case T_NIL:
return Qnil;
case T_FIXNUM:
case T_BIGNUM: ;
VALUE v = rb_int_modulo(b, INT2FIX(256));
unsigned char c = NUM2INT(v) & 0xFF;
b = rb_str_new((const char *)&c, 1);
break;
default:
SafeStringValue(b);
}
io_ungetbyte(b, fptr);
return Qnil;
}
|
#ungetc(integer) ⇒ nil #ungetc(string) ⇒ nil
Pushes back (“unshifts”) the given data onto the stream’s buffer, placing the data so that it is next to be read; returns nil
. See Character IO.
Note that:
-
Calling the method has no effect with unbuffered reads (such as IO#sysread).
-
Calling #rewind on the stream discards the pushed-back data.
When argument integer
is given, interprets the integer as a character:
File.write('t.tmp', '012')
f = File.open('t.tmp')
f.ungetc(0x41) # => nil
f.read # => "A012"
f.rewind
f.ungetc(0x0442) # => nil
f.getc.ord # => 1090
f.close
When argument string
is given, uses all characters:
File.write('t.tmp', '012')
f = File.open('t.tmp')
f.ungetc('A') # => nil
f.read # => "A012"
f.rewind
f.ungetc("\u0442\u0435\u0441\u0442") # => nil
f.getc.ord # => 1090
f.getc.ord # => 1077
f.getc.ord # => 1089
f.getc.ord # => 1090
f.close
5213 5214 5215 5216 5217 5218 5219 5220 5221 5222 5223 5224 5225 5226 5227 5228 5229 5230 5231 5232 5233 5234 5235 5236 5237 5238 5239 5240 5241 5242 5243 5244 5245 5246 5247 5248 5249 5250 5251 5252 5253 5254 5255 |
# File 'io.c', line 5213
VALUE
rb_io_ungetc(VALUE io, VALUE c)
{
rb_io_t *fptr;
long len;
GetOpenFile(io, fptr);
rb_io_check_char_readable(fptr);
if (FIXNUM_P(c)) {
c = rb_enc_uint_chr(FIX2UINT(c), io_read_encoding(fptr));
}
else if (RB_BIGNUM_TYPE_P(c)) {
c = rb_enc_uint_chr(NUM2UINT(c), io_read_encoding(fptr));
}
else {
SafeStringValue(c);
}
if (NEED_READCONV(fptr)) {
SET_BINARY_MODE(fptr);
len = RSTRING_LEN(c);
#if SIZEOF_LONG > SIZEOF_INT
if (len > INT_MAX)
rb_raise(rb_eIOError, "ungetc failed");
#endif
make_readconv(fptr, (int)len);
if (fptr->cbuf.capa - fptr->cbuf.len < len)
rb_raise(rb_eIOError, "ungetc failed");
if (fptr->cbuf.off < len) {
MEMMOVE(fptr->cbuf.ptr+fptr->cbuf.capa-fptr->cbuf.len,
fptr->cbuf.ptr+fptr->cbuf.off,
char, fptr->cbuf.len);
fptr->cbuf.off = fptr->cbuf.capa-fptr->cbuf.len;
}
fptr->cbuf.off -= (int)len;
fptr->cbuf.len += (int)len;
MEMMOVE(fptr->cbuf.ptr+fptr->cbuf.off, RSTRING_PTR(c), char, len);
}
else {
NEED_NEWLINE_DECORATOR_ON_READ_CHECK(fptr);
io_ungetbyte(c, fptr);
}
return Qnil;
}
|
#wait(events, timeout) ⇒ false? #wait(timeout = nil, mode = :read) ⇒ self, ...
Waits until the IO becomes ready for the specified events and returns the subset of events that become ready, or a falsy value when times out.
The events can be a bit mask of IO::READABLE
, IO::WRITABLE
or IO::PRIORITY
.
Returns an event mask (truthy value) immediately when buffered data is available.
Optional parameter mode
is one of :read
, :write
, or :read_write
.
9865 9866 9867 9868 9869 9870 9871 9872 9873 9874 9875 9876 9877 9878 9879 9880 9881 9882 9883 9884 9885 9886 9887 9888 9889 9890 9891 9892 9893 9894 9895 9896 9897 9898 9899 9900 9901 9902 9903 9904 9905 9906 9907 9908 9909 9910 9911 9912 9913 9914 9915 9916 9917 9918 |
# File 'io.c', line 9865
static VALUE
io_wait(int argc, VALUE *argv, VALUE io)
{
VALUE timeout = Qundef;
enum rb_io_event events = 0;
int return_io = 0;
// The documented signature for this method is actually incorrect.
// A single timeout is allowed in any position, and multiple symbols can be given.
// Whether this is intentional or not, I don't know, and as such I consider this to
// be a legacy/slow path.
if (argc != 2 || (RB_SYMBOL_P(argv[0]) || RB_SYMBOL_P(argv[1]))) {
// We'd prefer to return the actual mask, but this form would return the io itself:
return_io = 1;
// Slow/messy path:
for (int i = 0; i < argc; i += 1) {
if (RB_SYMBOL_P(argv[i])) {
events |= wait_mode_sym(argv[i]);
}
else if (UNDEF_P(timeout)) {
rb_time_interval(timeout = argv[i]);
}
else {
rb_raise(rb_eArgError, "timeout given more than once");
}
}
if (UNDEF_P(timeout)) timeout = Qnil;
if (events == 0) {
events = RUBY_IO_READABLE;
}
}
else /* argc == 2 and neither are symbols */ {
// This is the fast path:
events = io_event_from_value(argv[0]);
timeout = argv[1];
}
if (events & RUBY_IO_READABLE) {
rb_io_t *fptr = NULL;
RB_IO_POINTER(io, fptr);
if (rb_io_read_pending(fptr)) {
// This was the original behaviour:
if (return_io) return Qtrue;
// New behaviour always returns an event mask:
else return RB_INT2NUM(RUBY_IO_READABLE);
}
}
return io_wait_event(io, events, timeout, return_io);
}
|
#wait_priority ⇒ Object #wait_priority(timeout) ⇒ Object
Waits until IO is priority and returns a truthy value or a falsy value when times out. Priority data is sent and received using the Socket::MSG_OOB flag and is typically limited to streams.
9788 9789 9790 9791 9792 9793 9794 9795 9796 9797 9798 9799 9800 9801 9802 |
# File 'io.c', line 9788
static VALUE
io_wait_priority(int argc, VALUE *argv, VALUE io)
{
rb_io_t *fptr = NULL;
RB_IO_POINTER(io, fptr);
rb_io_check_readable(fptr);
if (rb_io_read_pending(fptr)) return Qtrue;
rb_check_arity(argc, 0, 1);
VALUE timeout = argc == 1 ? argv[0] : Qnil;
return io_wait_event(io, RUBY_IO_PRIORITY, timeout, 1);
}
|
#wait_readable ⇒ Object #wait_readable(timeout) ⇒ Object
Waits until IO is readable and returns a truthy value, or a falsy value when times out. Returns a truthy value immediately when buffered data is available.
9741 9742 9743 9744 9745 9746 9747 9748 9749 9750 9751 9752 9753 9754 9755 |
# File 'io.c', line 9741
static VALUE
io_wait_readable(int argc, VALUE *argv, VALUE io)
{
rb_io_t *fptr;
RB_IO_POINTER(io, fptr);
rb_io_check_readable(fptr);
if (rb_io_read_pending(fptr)) return Qtrue;
rb_check_arity(argc, 0, 1);
VALUE timeout = (argc == 1 ? argv[0] : Qnil);
return io_wait_event(io, RUBY_IO_READABLE, timeout, 1);
}
|
#wait_writable ⇒ Object #wait_writable(timeout) ⇒ Object
Waits until IO is writable and returns a truthy value or a falsy value when times out.
9765 9766 9767 9768 9769 9770 9771 9772 9773 9774 9775 9776 9777 |
# File 'io.c', line 9765
static VALUE
io_wait_writable(int argc, VALUE *argv, VALUE io)
{
rb_io_t *fptr;
RB_IO_POINTER(io, fptr);
rb_io_check_writable(fptr);
rb_check_arity(argc, 0, 1);
VALUE timeout = (argc == 1 ? argv[0] : Qnil);
return io_wait_event(io, RUBY_IO_WRITABLE, timeout, 1);
}
|
#write(*objects) ⇒ Integer
Writes each of the given objects
to self
, which must be opened for writing (see Access Modes); returns the total number bytes written; each of objects
that is not a string is converted via method to_s
:
$stdout.write('Hello', ', ', 'World!', "\n") # => 14
$stdout.write('foo', :bar, 2, "\n") # => 8
Output:
Hello, World!
foobar2
Related: IO#read.
2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 |
# File 'io.c', line 2262
static VALUE
io_write_m(int argc, VALUE *argv, VALUE io)
{
if (argc != 1) {
return io_writev(argc, argv, io);
}
else {
VALUE str = argv[0];
return io_write(io, str, 0);
}
}
|