class IO::Stream::Buffered
A buffered stream implementation that wraps an underlying IO object to provide efficient buffered reading and writing.
def self.open(path, mode = "r+", **options)
@parameter options [Hash] Additional options passed to the stream constructor.
@parameter mode [String] The file mode (e.g., "r+", "w", "a").
@parameter path [String] The file path to open.
Open a file and wrap it in a buffered stream.
def self.open(path, mode = "r+", **options) stream = self.new(::File.open(path, mode), **options) return stream unless block_given? begin yield stream ensure stream.close end end
def self.wrap(io, **options)
@parameter options [Hash] Additional options passed to the stream constructor.
@parameter io [IO] The IO object to wrap.
Wrap an existing IO object in a buffered stream.
def self.wrap(io, **options) if io.respond_to?(:buffered=) io.buffered = false elsif io.respond_to?(:sync=) io.sync = true end stream = self.new(io, **options) return stream unless block_given? begin yield stream ensure stream.close end end
def close_read
def close_read @io.close_read end
def close_write
def close_write super ensure @io.close_write end
def closed?
Check if the stream is closed.
def closed? @io.closed? end
def initialize(io, ...)
Initialize a new buffered stream.
def initialize(io, ...) super(...) @io = io if io.respond_to?(:timeout) @timeout = io.timeout else @timeout = nil end end
def readable?
Check if the stream is readable.
def readable? super && @io.readable? end
def sysclose
def sysclose # https://bugs.ruby-lang.org/issues/20723 Thread.new{@io.close}.join end
def sysclose
def sysclose @io.close end
def sysread(size, buffer)
def sysread(size, buffer) # Come on Ruby, why couldn't this just return `nil`? EOF is not exceptional. Every file has one. while true result = @io.read_nonblock(size, buffer, exception: false) case result when :wait_readable @io.wait_readable(@io.timeout) or raise ::IO::TimeoutError, "read timeout" when :wait_writable @io.wait_writable(@io.timeout) or raise ::IO::TimeoutError, "write timeout" else return result end end rescue OpenSSL::SSL::SSLError => error if error.message =~ /unexpected eof while reading/ raise ConnectionResetError, "Connection reset by peer!" end rescue Errno::ECONNRESET raise ConnectionResetError, "Connection reset by peer!" rescue Errno::EBADF raise ::IOError, "stream closed" end
def syswrite(buffer)
def syswrite(buffer) return @io.write(buffer) end
def syswrite(buffer)
def syswrite(buffer) while true result = @io.write_nonblock(buffer, exception: false) case result when :wait_readable @io.wait_readable(@io.timeout) or raise ::IO::TimeoutError, "read timeout" when :wait_writable @io.wait_writable(@io.timeout) or raise ::IO::TimeoutError, "write timeout" else if result == buffer.bytesize return else buffer = buffer.byteslice(result, buffer.bytesize) end end end end
def to_io
Get the underlying IO object.
def to_io @io.to_io end