On this page
- Extension io/console
- Example Files
- Open Options
- Basic IO
- Position
- Open and Closed Streams
- End-of-Stream
- Line IO
- Line Input
- Line Output
- Character IO
- Byte IO
- Codepoint IO
- What’s Here
- Creating
- Reading
- Writing
- Positioning
- Iterating
- Settings
- Querying
- Buffering
- Low-Level Access
- Other
- Class methods
- Instance methods
- Constants
- Ruby version changes
IO
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:
# English text with newlines. text = <<~EOT First line Second line Fourth line Fifth line EOT # Russian text. russian = "\u{442 435 441 442}" # => "тест" # Binary data. data = "\u9990\u9991\u9992\u9993\u9994" # Text file. File.write('t.txt', text) # File with Russian text. File.write('t.rus', russian) # File with binary data. f = File.new('t.dat', 'wb:UTF-16') f.write(data) f.close
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:Integerfile open flags; Ifmodeis 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 isnilno 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 thefdwill close when the stream closes; otherwise it remains open. -
:path:If a string value is provided, it is used ininspectand is available aspathmethod.
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 viato_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.
These methods discard buffers and the Encoding::Converter instances used for that IO.
The relevant methods:
-
IO#tell(aliased aspos): Returns the current position (in bytes) in the stream. -
IO#pos=: Sets the position of the stream to a given integernew_position(in bytes). -
IO#seek: Sets the position of the stream to a given integeroffset(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:
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
Class IO supports line-oriented input and output
Line Input
Class IO supports line-oriented input for files and IO streams
File Line Input
You can read lines from a file using these methods:
-
IO.foreach: Reads each line and passes it to the given block. -
IO.readlines: Reads and returns all lines in an array.
For each of these methods:
-
You can specify open options.
-
Line parsing depends on the effective line separator; see Line Separator.
-
The length of each returned line depends on the effective line limit; see Line Limit.
Stream Line Input
You can read lines from an IO stream using these methods:
-
IO#each_line: Reads each remaining line, passing it to the given block. -
IO#gets: Returns the next line. -
IO#readline: Likegets, but raises an exception at end-of-stream. -
IO#readlines: Returns all remaining lines in an array.
For each of these methods:
-
Reading may begin mid-line, depending on the stream’s position; see Position.
-
Line parsing depends on the effective line separator; see Line Separator.
-
The length of each returned line depends on the effective line limit; see Line Limit.
Line Separator
Each of the line input methods uses a line separator: the string that determines what is considered a line; it is sometimes called the input record separator.
The default line separator is taken from global variable $/, whose initial value is "\n".
Generally, the line to be read next is all data from the current position to the next line separator (but see Special Line Separator Values):
f = File.new('t.txt') # Method gets with no sep argument returns the next line, according to $/. 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 use a different line separator by passing argument sep:
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
Or by setting global variable $/:
f = File.new('t.txt') $/ = 'l' f.gets # => "First l" f.gets # => "ine\nSecond l" f.gets # => "ine\n\nFourth l" f.close
Special Line Separator Values
Each of the line input methods accepts two special values for parameter sep:
-
nil: The entire stream is to be read (“slurped”) into a single string:Examplef = 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 to be read (paragraphs being separated by two consecutive line separators):Examplef = 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 the line input methods uses an integer line limit, which restricts the number of bytes that may be returned. (A multi-byte character will not be split, and so a returned line may be slightly longer than the limit).
The default limit value is -1; any negative limit value means that there is no limit.
If there is no limit, 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
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:
-
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 effective line separator:
-
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:Example$. = 41 f = File.new('t.txt') $. = 41 # => 41 f.close
-
When a stream is read,
$.is set to the line number for that stream:Examplef0 = 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#rewindandIO#seekdo not affect$.:Examplef = 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
Line Output
You can write to an IO stream line-by-line using this method:
-
IO#puts: Writes objects to the stream.
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: Likegetc, 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: Likegetbyte, 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 fromselfas an integer. -
getc: Returns the next character read fromselfas a string. -
gets: Returns the line read fromself. -
pread: Returns all or the next n bytes read fromself, not updating the receiver’s offset. -
read: Returns all remaining or the next n bytes read fromselffor a given n. -
read_nonblock: the next n bytes read fromselffor a given n, in non-block mode. -
readbyte: Returns the next byte read fromself; same asgetbyte, but raises an exception on end-of-stream. -
readchar: Returns the next character read fromself; same asgetc, but raises an exception on end-of-stream. -
readline: Returns the next line read fromself; same as getline, but raises an exception of end-of-stream. -
readlines: Returns an array of all lines read read fromself. -
readpartial: Returns up to the given number of bytes fromself.
Writing
-
::binwrite: Writes the given string to the file at the given filepath, in binary mode. -
::write: Writes the given string toself. -
<<: Appends the given string toself. -
print: Prints last read line or given objects toself. -
printf: Writes toselfbased on the given format string and objects. -
putc: Writes a character toself. -
puts: Writes lines toself, 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 toself. -
write_nonblock: Writes one or more given strings toselfin non-blocking mode.
Positioning
-
lineno: Returns the current line number inself. -
lineno=: Sets the line number isself. -
pos(aliased astell): Returns the current byte offset inself. -
pos=: Sets the byte offset inself. -
reopen: Reassociatesselfwith a new or existing IO stream. -
rewind: Positionsselfto the beginning of input. -
seek: Sets the offset forselfrelative to given position.
Iterating
-
::foreach: Yields each line of given file to the block. -
each(aliased aseach_line): Calls the given block with each successive line inself. -
each_byte: Calls the given block with each successive byte inselfas an integer. -
each_char: Calls the given block with each successive character inselfas a string. -
each_codepoint: Calls the given block with each successive codepoint inselfas an integer.
Settings
-
autoclose=: Sets whetherselfauto-closes. -
binmode: Setsselfto binary mode. -
close: Closesself. -
close_on_exec=: Sets the close-on-exec flag. -
close_read: Closesselffor reading. -
close_write: Closesselffor writing. -
set_encoding: Sets the encoding forself. -
set_encoding_by_bom: Sets the encoding forself, based on its Unicode byte-order-mark. -
sync=: Sets the sync-mode to the given value.
Querying
-
autoclose?: Returns whetherselfauto-closes. -
binmode?: Returns whetherselfis in binary mode. -
close_on_exec?: Returns the close-on-exec flag forself. -
closed?: Returns whetherselfis closed. -
eof?(aliased aseof): Returns whetherselfis at end-of-stream. -
external_encoding: Returns the external encoding object forself. -
fileno(aliased asto_i): Returns the integer file descriptor forself -
internal_encoding: Returns the internal encoding object forself. -
pid: Returns the process ID of a child process associated withself, ifselfwas created by::popen. -
stat: Returns theFile::Statobject containing status information forself. -
sync: Returns whetherselfis in sync-mode. -
tty?(aliased asisatty): Returns whetherselfis a terminal.
Buffering
-
fdatasync: Immediately writes all buffered data inselfto disk. -
flush: Flushes any buffered data withinselfto the underlying operating system. -
fsync: Immediately writes all buffered data and attributes inselfto disk. -
ungetbyte: Prepends buffer forselfwith given integer byte or string. -
ungetc: Prepends buffer forselfwith 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 fromselfin 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 forself. -
syswrite: Writes the given string toselfusing 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 ofself.
Class methods 16
Instance methods 115
Set I/O position from the current position
Set I/O position to the next location containing data
Set I/O position from the end
Set I/O position to the next hole
Set I/O position from the beginning
Ruby version changes 8
-
4.0
-
Reintroduce the
Fiber::Scheduler#io_closehook for asynchronousIO#close. -
IO.selectacceptsFloat::INFINITYas a timeout argument. [Feature #20610] -
A deprecated behavior, process creation by
IOclass methods with a leading|, was removed. [Feature #19630]
-
-
3.2
-
Introduce
Fiber::Scheduler#io_selectfor non-blockingIO.select. [Feature #19060] -
Introduce
IO#timeout=andIO#timeoutwhich can causeIO::TimeoutErrorto be raised if a blocking operation exceeds the specified timeout. [Feature #18630]ExampleSTDIN.timeout = 1 STDIN.read # => Blocking operation timed out! (IO::TimeoutError)
-
Introduce
IO.new(..., path:)and promoteFile#pathtoIO#path. [Feature #19036]
-
-
3.0
-
IO#nonblock?now defaults totrue. [Feature #16786] -
IO#wait_readable,IO#wait_writable,IO#read,IO#writeand other related methods (e.g.IO#puts,IO#gets) may invoke the scheduler hook io_wait(io, events, timeout) in a non-blocking execution context. [Feature #16786]
-