Class: IO (Ruby 2.3.4)

    In Files

    • file.c
    • io.c
    • prelude.rb

    Class/Module Index [+]

    Quicksearch

    IO

    The IO class is the basis for all input and output in Ruby. An I/O stream may be duplexed (that is, bidirectional), and so may use more than one native operating system stream.

    Many of the examples in this section use the File class, the only standard subclass of IO. The two classes are closely associated. Like the File class, the Socket library subclasses from IO (such as TCPSocket or UDPSocket).

    The Kernel#open method can create an IO (or File) object for these types of arguments:

    • A plain string represents a filename suitable for the underlying operating system.

    • A string starting with "|" indicates a subprocess. The remainder of the string following the "|" is invoked as a process with appropriate input/output channels connected to it.

    • A string equal to "|-" will create another Ruby instance as a subprocess.

    The IO may be opened with different file modes (read-only, write-only) and encodings for proper conversion. See ::new for these options. See Kernel#open for details of the various command formats described above.

    ::popen, the Open3 library, or Process#spawn may also be used to communicate with subprocesses through an IO.

    Ruby will convert pathnames between different operating system conventions if possible. For instance, on a Windows system the filename "/gumby/ruby/test.rb" will be opened as "\gumby\ruby\test.rb". When specifying a Windows-style filename in a Ruby string, remember to escape the backslashes:

    "c:\\gumby\\ruby\\test.rb"
    

    Our examples here will use the Unix-style forward slashes; File::ALT_SEPARATOR can be used to get the platform-specific separator character.

    The global constant ARGF (also accessible as $<) provides an IO-like stream which allows access to all files mentioned on the command line (or STDIN if no files are mentioned). ARGF#path and its alias ARGF#filename are provided to access the name of the file currently being read.

    io/console

    The io/console extension provides methods for interacting with the console. The console can be accessed from IO.console or the standard input/output/error IO objects.

    Requiring io/console adds the following methods:

    • IO::console

    • IO#raw

    • IO#raw!

    • IO#cooked

    • IO#cooked!

    • IO#getch

    • IO#echo=

    • IO#echo?

    • IO#noecho

    • IO#winsize

    • IO#winsize=

    • IO#iflush

    • IO#ioflush

    • IO#oflush

    Example:

    require 'io/console'
    rows, columns = $stdout.winsize
    puts "Your screen is #{columns} wide and #{rows} tall"
    

    Constants

    EWOULDBLOCKWaitReadable

    EAGAINWaitReadable

    EWOULDBLOCKWaitWritable

    EAGAINWaitWritable

    SEEK_CUR

    Set I/O position from the current position

    SEEK_DATA

    Set I/O position to the next location containing data

    SEEK_END

    Set I/O position from the end

    SEEK_HOLE

    Set I/O position to the next hole

    SEEK_SET

    Set I/O position from the beginning

    Public Class Methods

    binread(name, [length [, offset]] ) → string click to toggle source

    Opens the file, optionally seeks to the given offset, then returns length bytes (defaulting to the rest of the file). binread ensures the file is closed before returning. The open mode would be “rb:ASCII-8BIT”.

    IO.binread("testfile")           #=> "This is line one\nThis is line two\nThis is line three\nAnd so on...\n"
    IO.binread("testfile", 20)       #=> "This is line one\nThi"
    IO.binread("testfile", 20, 10)   #=> "ne one\nThis is line "
    
     
                   static VALUE
    rb_io_s_binread(int argc, VALUE *argv, VALUE io)
    {
        VALUE offset;
        struct foreach_arg arg;
    
        rb_scan_args(argc, argv, "12", NULL, NULL, &offset);
        FilePathValue(argv[0]);
        arg.io = rb_io_open(argv[0], rb_str_new_cstr("rb:ASCII-8BIT"), Qnil, Qnil);
        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(name, string, [offset] ) → integer click to toggle source
    binwrite(name, string, [offset], open_args ) → integer

    Same as IO.write except opening the file in binary mode and ASCII-8BIT encoding (“wb:ASCII-8BIT”).

     
                   static VALUE
    rb_io_s_binwrite(int argc, VALUE *argv, VALUE io)
    {
        return io_s_write(argc, argv, 1);
    }
                
    copy_stream(src, dst) click to toggle source
    copy_stream(src, dst, copy_length)
    copy_stream(src, dst, copy_length, src_offset)

    ::copy_stream copies src to dst. src and dst is either a filename or an IO.

    This method returns the number of bytes copied.

    If optional arguments are not given, the start position of the copy is the beginning of the filename or the current file offset of the IO. The end position of the copy is the end of file.

    If copy_length is given, No more than copy_length bytes are copied.

    If src_offset is given, it specifies the start position of the copy.

    When src_offset is specified and src is an IO, ::copy_stream doesn’t move the current file offset.

     
                   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;
    
        if (NIL_P(length))
            st.copy_length = (off_t)-1;
        else
            st.copy_length = NUM2OFFT(length);
    
        if (NIL_P(src_offset))
            st.src_offset = (off_t)-1;
        else
            st.src_offset = NUM2OFFT(src_offset);
    
        rb_fd_init(&st.fds);
        rb_ensure(copy_stream_body, (VALUE)&st, copy_stream_finalize, (VALUE)&st);
    
        return OFFT2NUM(st.total);
    }
                
    for_fd(fd, mode [, opt]) → io click to toggle source

    Synonym for IO.new.

     
                   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(name, sep=$/ [, open_args]) {|line| block } → nil click to toggle source
    foreach(name, limit [, open_args]) {|line| block } → nil
    foreach(name, sep, limit [, open_args]) {|line| block } → nil
    foreach(...) → an_enumerator

    Executes the block for every line in the named I/O port, where lines are separated by sep.

    If no block is given, an enumerator is returned instead.

    IO.foreach("testfile") {|x| print "GOT ", x }
    

    produces:

    GOT This is line one
    GOT This is line two
    GOT This is line three
    GOT And so on...

    If the last argument is a hash, it’s the keyword argument to open. See IO.read for detail.

     
                   static VALUE
    rb_io_s_foreach(int argc, VALUE *argv, VALUE self)
    {
        VALUE opt;
        int orig_argc = argc;
        struct foreach_arg arg;
    
        argc = rb_scan_args(argc, argv, "13:", NULL, NULL, NULL, NULL, &opt);
        RETURN_ENUMERATOR(self, orig_argc, argv);
        open_key_args(argc, argv, opt, &arg);
        if (NIL_P(arg.io)) return Qnil;
        return rb_ensure(io_s_foreach, (VALUE)&arg, rb_io_close, arg.io);
    }
                
    new(fd [, mode] [, opt]) → io click to toggle source

    Returns a new IO object (a stream) for the given integer file descriptor fd and mode string. opt may be used to specify parts of mode in a more readable fashion. See also ::sysopen and ::for_fd.

    ::new is called by various File and IO opening methods such as ::open, Kernel#open, and File.open.

    Open Mode

    When mode is an integer it must be combination of the modes defined in File::Constants (File::RDONLY, +File::WRONLY | File::CREAT+). See the open(2) man page for more information.

    When mode is a string it must be in one of the following forms:

    fmode
    fmode ":" ext_enc
    fmode ":" ext_enc ":" int_enc
    fmode ":" "BOM|UTF-*"

    fmode is an IO open mode string, ext_enc is the external encoding for the IO and int_enc is the internal encoding.

    IO Open Mode

    Ruby allows the following open modes:

    "r"  Read-only, starts at beginning of file  (default mode).
    
    "r+" Read-write, starts at beginning of file.
    
    "w"  Write-only, truncates existing file
         to zero length or creates a new file for writing.
    
    "w+" Read-write, truncates existing file to zero length
         or creates a new file for reading and writing.
    
    "a"  Write-only, each write call appends data at end of file.
         Creates a new file for writing if file does not exist.
    
    "a+" Read-write, each write call appends data at end of file.
         Creates a new file for reading and writing if file does
         not exist.

    The following modes must be used separately, and along with one or more of the modes seen above.

    "b"  Binary file mode
         Suppresses EOL <-> CRLF conversion on Windows. And
         sets external encoding to ASCII-8BIT unless explicitly
         specified.
    
    "t"  Text file mode

    When the open mode of original IO is read only, the mode cannot be changed to be writable. Similarly, the open mode cannot be changed from write only to readable.

    When such a change is attempted the error is raised in different locations according to the platform.

    IO Encoding

    When ext_enc is specified, strings read will be tagged by the encoding when reading, and strings output will be converted to the specified encoding when writing.

    When ext_enc and int_enc are specified read strings will be converted from ext_enc to int_enc upon input, and written strings will be converted from int_enc to ext_enc upon output. See Encoding for further details of transcoding on input and output.

    If “BOM|UTF-8”, “BOM|UTF-16LE” or “BOM|UTF16-BE” are used, Ruby checks for a Unicode BOM in the input document to help determine the encoding. For UTF-16 encodings the file open mode must be binary. When present, the BOM is stripped and the external encoding from the BOM is used. When the BOM is missing the given Unicode encoding is used as ext_enc. (The BOM-set encoding option is case insensitive, so “bom|utf-8” is also valid.)

    Options

    opt can be used instead of mode for improved readability. The following keys are supported:

    :mode

    Same as mode parameter

    :flags

    Specifies file open flags as integer. If mode parameter is given, this parameter will be bitwise-ORed.

    :external_encoding

    External encoding for the IO. “-” is a synonym for the default external encoding.

    :internal_encoding

    Internal encoding for the IO. “-” is a synonym for the default internal encoding.

    If the value is nil no conversion occurs.

    :encoding

    Specifies external and internal encodings as “extern:intern”.

    :textmode

    If the value is truth value, same as “t” in argument mode.

    :binmode

    If the value is truth value, same as “b” in argument mode.

    :autoclose

    If the value is false, the fd will be kept open after this IO instance gets finalized.

    Also, opt can have same keys in String#encode for controlling conversion between the external encoding and the internal encoding.

    Example 1

    fd = IO.sysopen("/dev/tty", "w")
    a = IO.new(fd,"w")
    $stderr.puts "Hello"
    a.puts "World"
    

    Produces:

    Hello
    World
    

    Example 2

    require 'fcntl'
    
    fd = STDERR.fcntl(Fcntl::F_DUPFD)
    io = IO.new(fd, mode: 'w:UTF-16LE', cr_newline: true)
    io.puts "Hello, World!"
    
    fd = STDERR.fcntl(Fcntl::F_DUPFD)
    io = IO.new(fd, mode: 'w', cr_newline: true,
                external_encoding: Encoding::UTF_16LE)
    io.puts "Hello, World!"
    

    Both of above print “Hello, World!” in UTF-16LE to standard error output with converting EOL generated by puts to CR.

     
                   static VALUE
    rb_io_initialize(int argc, VALUE *argv, VALUE io)
    {
        VALUE fnum, vmode;
        rb_io_t *fp;
        int fd, fmode, oflags = O_RDONLY;
        convconfig_t 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) == -1) 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
        if (!NIL_P(opt) && rb_hash_aref(opt, sym_autoclose) == Qfalse) {
            fmode |= FMODE_PREP;
        }
        MakeOpenFile(io, fp);
        fp->fd = fd;
        fp->mode = fmode;
        fp->encs = convconfig;
        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;
    }
                
    open(fd, mode="r" [, opt]) → io click to toggle source
    open(fd, mode="r" [, opt]) {|io| block } → obj

    With no associated block, IO.open is a synonym for ::new. If the optional code block is given, it will be passed io as an argument, and the IO object will automatically be closed when the block terminates. In this instance, ::open returns the value of the block.

    See ::new for a description of the fd, mode and opt parameters.

     
                   static VALUE
    rb_io_s_open(int argc, VALUE *argv, VALUE klass)
    {
        VALUE io = rb_class_new_instance(argc, argv, klass);
    
        if (rb_block_given_p()) {
            return rb_ensure(rb_yield, io, io_close, io);
        }
    
        return io;
    }
                
    pipe → [read_io, write_io] click to toggle source
    pipe(ext_enc) → [read_io, write_io]
    pipe("ext_enc:int_enc" [, opt]) → [read_io, write_io]
    pipe(ext_enc, int_enc [, opt]) → [read_io, write_io]
    pipe(...) {|read_io, write_io| ... }

    Creates a pair of pipe endpoints (connected to each other) and returns them as a two-element array of IO objects: [ read_io, write_io ].

    If a block is given, the block is called and returns the value of the block. read_io and write_io are sent to the block as arguments. If read_io and write_io are not closed when the block exits, they are closed. i.e. closing read_io and/or write_io doesn’t cause an error.

    Not available on all platforms.

    If an encoding (encoding name or encoding object) is specified as an optional argument, read string from pipe is tagged with the encoding specified. If the argument is a colon separated two encoding names “A:B”, the read string is converted from encoding A (external encoding) to encoding B (internal encoding), then tagged with B. If two optional arguments are specified, those must be encoding objects or encoding names, and the first one is the external encoding, and the second one is the internal encoding. If the external encoding and the internal encoding is specified, optional hash argument specify the conversion option.

    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>
     
                   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) == -1)
            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 DEFAULT_TEXTMODE
        if ((fptr->mode & FMODE_TEXTMODE) && (fmode & FMODE_BINMODE)) {
            fptr->mode &= ~FMODE_TEXTMODE;
            setmode(fptr->fd, O_BINARY);
        }
    #if defined(RUBY_TEST_CRLF_ENVIRONMENT) || defined(_WIN32)
        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" [, opt]) → io click to toggle source
    popen([env,] cmd, mode="r" [, opt]) {|io| block } → obj

    Runs the specified command as a subprocess; the subprocess’s standard input and output will be connected to the returned IO object.

    The PID of the started process can be obtained by #pid method.

    cmd is a string or an array as follows.

    cmd:
      "-"                                      : fork
      commandline                              : command line string which is passed to a shell
      [env, cmdname, arg1, ..., opts]          : command name and zero or more arguments (no shell)
      [env, [cmdname, argv0], arg1, ..., opts] : command name, argv[0] and zero or more arguments (no shell)
    (env and opts are optional.)

    If cmd is a String-”, then a new instance of Ruby is started as the subprocess.

    If cmd is an Array of String, then it will be used as the subprocess’s argv bypassing a shell. The array can contains a hash at first for environments and a hash at last for options similar to spawn.

    The default mode for the new file object is “r”, but mode may be set to any of the modes listed in the description for class IO. The last argument opt qualifies mode.

    # 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
    # spawn option.  See the document of Kernel.spawn.
    IO.popen(["ls", "/", :err=>[:child, :out]]) {|ls_io|
      ls_result_with_error = ls_io.read
    }
    
    # spawn options can be mixed with IO options
    IO.popen(["ls", "/"], :err=>[:child, :out]) {|ls_io|
      ls_result_with_error = ls_io.read
    }
    

    Raises exceptions which IO.pipe and Kernel.spawn raise.

    If a block is given, Ruby will run the command as a child connected to Ruby with a pipe. Ruby’s end of the pipe will be passed as a parameter to the block. At the end of block, Ruby closes the pipe and sets $?. In this case IO.popen returns the value of the block.

    If a block is given with a cmd of “-”, the block will be run in two separate processes: once in the parent, and once in a child. The parent process will be passed the pipe object as a parameter to the block, the child version of the block will be passed nil, and the child’s standard in and standard out will be connected to the parent through the pipe. Not available on all platforms.

    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
    }
    

    produces:

    ["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;
     
                   static VALUE
    rb_io_s_popen(int argc, VALUE *argv, VALUE klass)
    {
        const char *modestr;
        VALUE pname, pmode = Qnil, port, tmp, opt = Qnil, env = Qnil, execarg_obj = Qnil;
        int oflags, fmode;
        convconfig_t convconfig;
    
        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);
            }
        }
    
        tmp = rb_check_array_type(pname);
        if (!NIL_P(tmp)) {
            long len = RARRAY_LEN(tmp);
    #if SIZEOF_LONG > SIZEOF_INT
            if (len > INT_MAX) {
                rb_raise(rb_eArgError, "too many arguments");
            }
    #endif
            execarg_obj = rb_execarg_new((int)len, RARRAY_CONST_PTR(tmp), FALSE);
            RB_GC_GUARD(tmp);
        }
        else {
            SafeStringValue(pname);
            execarg_obj = Qnil;
            if (!is_popen_fork(pname))
                execarg_obj = rb_execarg_new(1, &pname, TRUE);
        }
        if (!NIL_P(execarg_obj)) {
            if (!NIL_P(opt))
                opt = rb_execarg_extract_options(execarg_obj, opt);
            if (!NIL_P(env))
                rb_execarg_setenv(execarg_obj, env);
        }
        rb_io_extract_modeenc(&pmode, 0, opt, &oflags, &fmode, &convconfig);
        modestr = rb_io_oflags_modestr(oflags);
    
        port = pipe_open(execarg_obj, modestr, fmode, &convconfig);
        if (NIL_P(port)) {
            /* child */
            if (rb_block_given_p()) {
                rb_yield(Qnil);
                rb_io_flush(rb_stdout);
                rb_io_flush(rb_stderr);
                _exit(0);
            }
            return Qnil;
        }
        RBASIC_SET_CLASS(port, klass);
        if (rb_block_given_p()) {
            return rb_ensure(rb_yield, port, pipe_close, port);
        }
        return port;
    }
                
    read(name, [length [, offset]] [, opt] ) → string click to toggle source

    Opens the file, optionally seeks to the given offset, then returns length bytes (defaulting to the rest of the file). read ensures the file is closed before returning.

    Options

    The options hash accepts the following keys:

    encoding

    string or encoding

    Specifies the encoding of the read string. encoding: will be ignored if length is specified. See Encoding.aliases for possible encodings.

    mode

    string

    Specifies the mode argument for open(). It must start with an “r” otherwise it will cause an error. See ::new for the list of possible modes.

    open_args

    array of strings

    Specifies arguments for open() as an array. This key can not be used in combination with either encoding: or mode:.

    Examples:

    IO.read("testfile")              #=> "This is line one\nThis is line two\nThis is line three\nAnd so on...\n"
    IO.read("testfile", 20)          #=> "This is line one\nThi"
    IO.read("testfile", 20, 10)      #=> "ne one\nThis is line "
    IO.read("binfile", mode: "rb")   #=> "\xF7\x00\x00\x0E\x12"
    
     
                   static VALUE
    rb_io_s_read(int argc, VALUE *argv, VALUE io)
    {
        VALUE opt, offset;
        struct foreach_arg arg;
    
        argc = rb_scan_args(argc, argv, "13:", NULL, NULL, &offset, NULL, &opt);
        open_key_args(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(name, sep=$/ [, open_args]) → array click to toggle source
    readlines(name, limit [, open_args]) → array
    readlines(name, sep, limit [, open_args]) → array

    Reads the entire file specified by name as individual lines, and returns those lines in an array. Lines are separated by sep.

    a = IO.readlines("testfile")
    a[0]   #=> "This is line one\n"
    

    If the last argument is a hash, it’s the keyword argument to open. See IO.read for detail.

     
                   static VALUE
    rb_io_s_readlines(int argc, VALUE *argv, VALUE io)
    {
        VALUE opt;
        struct foreach_arg arg;
    
        argc = rb_scan_args(argc, argv, "13:", NULL, NULL, NULL, NULL, &opt);
        open_key_args(argc, argv, opt, &arg);
        if (NIL_P(arg.io)) return Qnil;
        return rb_ensure(io_s_readlines, (VALUE)&arg, rb_io_close, arg.io);
    }
                
    select(read_array [, write_array [, error_array [, timeout]]]) → array or nil click to toggle source

    Calls select(2) system call. It monitors given arrays of IO objects, waits until one or more of IO objects are ready for reading, are ready for writing, and have pending exceptions respectively, and returns an array that contains arrays of those IO objects. It will return nil if optional timeout value is given and no IO object is ready in timeout seconds.

    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 nonblocking 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 nonblocking 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 blocks.

    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 nonblocking 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) manual on GNU/Linux system.

    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 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
    

    Parameters

    read_array

    an array of IO objects that wait until ready for read

    write_array

    an array of IO objects that wait until ready for write

    error_array

    an array of IO objects that wait for exceptions

    timeout

    a numeric value in second

    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
    }
    

    produces:

    ping pong
    ping pong
    ping pong
    (snipped)
    ping
    
     
                   static VALUE
    rb_f_select(int argc, VALUE *argv, VALUE obj)
    {
        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, [perm]]) → fixnum click to toggle source

    Opens the given path, returning the underlying file descriptor as a Fixnum.

    IO.sysopen("testfile")   #=> 3
    
     
                   static VALUE
    rb_io_s_sysopen(int argc, VALUE *argv)
    {
        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(obj) → io or nil click to toggle source

    Try to convert obj into an IO, using #to_io method. Returns converted IO or nil if obj cannot be converted for any reason.

    IO.try_convert(STDOUT)     #=> STDOUT
    IO.try_convert("STDOUT")   #=> nil
    
    require 'zlib'
    f = open("/tmp/zz.gz")       #=> #<File:/tmp/zz.gz>
    z = Zlib::GzipReader.open(f) #=> #<Zlib::GzipReader:0x81d8744>
    IO.try_convert(z)            #=> #<File:/tmp/zz.gz>
    
     
                   static VALUE
    rb_io_s_try_convert(VALUE dummy, VALUE io)
    {
        return rb_io_check_io(io);
    }
                
    write(name, string, [offset] ) => fixnum click to toggle source
    write(name, string, [offset], open_args ) => fixnum

    Opens the file, optionally seeks to the given offset, writes string, then returns the length written. write ensures the file is closed before returning. If offset is not given, the file is truncated. Otherwise, it is not truncated.

    If the last argument is a hash, it specifies option for internal open(). The key would be the following. open_args: is exclusive to others.

    encoding: string or encoding
    
     specifies encoding of the read string.  encoding will be ignored
     if length is specified.
    
    mode: string
    
     specifies mode argument for open().  it should start with "w" or "a" or "r+"
     otherwise it would cause error.
    
    perm: fixnum
    
     specifies perm argument for open().
    
    open_args: array
    
     specifies arguments for open() as an array.
    
      IO.write("testfile", "0123456789", 20) # => 10
      # File could contain:  "This is line one\nThi0123456789two\nThis is line three\nAnd so on...\n"
      IO.write("testfile", "0123456789")      #=> 10
      # File would now read: "0123456789"
     
                   static VALUE
    rb_io_s_write(int argc, VALUE *argv, VALUE io)
    {
        return io_s_write(argc, argv, 0);
    }
                

    Public Instance Methods

    ios << obj → ios click to toggle source

    String Output---Writes obj to ios. obj will be converted to a string using to_s.

    $stdout << "Hello " << "world!\n"
    

    produces:

    Hello world!
    
     
                   VALUE
    rb_io_addstr(VALUE io, VALUE str)
    {
        rb_io_write(io, str);
        return io;
    }
                
    advise(advice, offset=0, len=0) → nil click to toggle source

    Announce an intention to access data from the current file in a specific pattern. On platforms that do not support the posix_fadvise(2) system call, this method is a no-op.

    advice is one of the following symbols:

    :normal

    No advice to give; the default assumption for an open file.

    :sequential

    The data will be accessed sequentially with lower offsets read before higher ones.

    :random

    The data will be accessed in random order.

    :willneed

    The data will be accessed in the near future.

    :dontneed

    The data will not be accessed in the near future.

    :noreuse

    The data will only be accessed once.

    The semantics of a piece of advice are platform-dependent. See man 2 posix_fadvise for details.

    “data” means the region of the current file that begins at offset and extends for len bytes. If len is 0, the region ends at the last byte of the file. By default, both offset and len are 0, meaning that the advice applies to the entire file.

    If an error occurs, one of the following exceptions will be raised:

    IOError

    The IO stream is closed.

    Errno::EBADF

    The file descriptor of the current file is invalid.

    Errno::EINVAL

    An invalid value for advice was given.

    Errno::ESPIPE

    The file descriptor of the current file refers to a FIFO or pipe. (Linux raises Errno::EINVAL in this case).

    TypeError

    Either advice was not a Symbol, or one of the other arguments was not an Integer.

    RangeError

    One of the arguments given was too big/small.

    This list is not exhaustive; other Errno

    exceptions are also possible.

     
                   static VALUE
    rb_io_advise(int argc, VALUE *argv, VALUE io)
    {
        VALUE advice, offset, len;
        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 → true or false click to toggle source

    Sets auto-close flag.

    f = open("/dev/null")
    IO.for_fd(f.fileno)
    # ...
    f.gets # may cause IOError
    
    f = open("/dev/null")
    IO.for_fd(f.fileno).autoclose = true
    # ...
    f.gets # won't cause IOError
    
     
                   static VALUE
    rb_io_set_autoclose(VALUE io, VALUE autoclose)
    {
        rb_io_t *fptr;
        GetOpenFile(io, fptr);
        if (!RTEST(autoclose))
            fptr->mode |= FMODE_PREP;
        else
            fptr->mode &= ~FMODE_PREP;
        return io;
    }
                
    autoclose? → true or false click to toggle source

    Returns true if the underlying file descriptor of ios will be closed automatically at its finalization, otherwise false.

     
                   static VALUE
    rb_io_autoclose_p(VALUE io)
    {
        rb_io_t *fptr = RFILE(io)->fptr;
        rb_io_check_closed(fptr);
        return (fptr->mode & FMODE_PREP) ? Qfalse : Qtrue;
    }
                
    binmode → ios click to toggle source

    Puts ios into binary mode. Once a stream is in binary mode, it cannot be reset to nonbinary mode.

    • newline conversion disabled

    • encoding conversion disabled

    • content is treated as ASCII-8BIT

     
                   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? → true or false click to toggle source

    Returns true if ios is binmode.

     
                   static VALUE
    rb_io_binmode_p(VALUE io)
    {
        rb_io_t *fptr;
        GetOpenFile(io, fptr);
        return fptr->mode & FMODE_BINMODE ? Qtrue : Qfalse;
    }
                
    bytes() click to toggle source

    This is a deprecated alias for each_byte.

     
                   static VALUE
    rb_io_bytes(VALUE io)
    {
        rb_warn("IO#bytes is deprecated; use #each_byte instead");
        if (!rb_block_given_p())
            return rb_enumeratorize(io, ID2SYM(rb_intern("each_byte")), 0, 0);
        return rb_io_each_byte(io);
    }
                
    chars() click to toggle source

    This is a deprecated alias for each_char.

     
                   static VALUE
    rb_io_chars(VALUE io)
    {
        rb_warn("IO#chars is deprecated; use #each_char instead");
        if (!rb_block_given_p())
            return rb_enumeratorize(io, ID2SYM(rb_intern("each_char")), 0, 0);
        return rb_io_each_char(io);
    }
                
    close → nil click to toggle source

    Closes ios and flushes any pending writes to the operating system. The stream is unavailable for any further data operations; an IOError is raised if such an attempt is made. I/O streams are automatically closed when they are claimed by the garbage collector.

    If ios is opened by IO.popen, close sets $?.

    Calling this method on closed IO object is just ignored since Ruby 2.3.

     
                   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 → true or false click to toggle source

    Sets a close-on-exec flag.

    f = open("/dev/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.

     
                   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 == -1) 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 == -1) rb_sys_fail_path(fptr->pathv);
            }
        }
        return Qnil;
    }
                
    close_on_exec? → true or false click to toggle source

    Returns true if ios will be closed on exec.

    f = open("/dev/null")
    f.close_on_exec?                 #=> false
    f.close_on_exec = true
    f.close_on_exec?                 #=> true
    f.close_on_exec = false
    f.close_on_exec?                 #=> false
    
     
                   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 click to toggle source

    Closes the read end of a duplex I/O stream (i.e., one that contains both a read and a write stream, such as a pipe). Will raise an IOError if the stream is not duplexed.

    f = IO.popen("/bin/sh","r+")
    f.close_read
    f.readlines
    

    produces:

    prog.rb:3:in `readlines': not opened for reading (IOError)
     from prog.rb:3
     
                   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 click to toggle source

    Closes the write end of a duplex I/O stream (i.e., one that contains both a read and a write stream, such as a pipe). Will raise an IOError if the stream is not duplexed.

    f = IO.popen("/bin/sh","r+")
    f.close_write
    f.print "nowhere"
    

    produces:

    prog.rb:3:in `write': not opened for writing (IOError)
     from prog.rb:3:in `print'
     from prog.rb:3
     
                   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? → true or false click to toggle source

    Returns true if ios is completely closed (for duplex streams, both reader and writer), false otherwise.

    f = File.new("testfile")
    f.close         #=> nil
    f.closed?       #=> true
    f = IO.popen("/bin/sh","r+")
    f.close_write   #=> nil
    f.closed?       #=> false
    f.close_read    #=> nil
    f.closed?       #=> true
    
     
                   static VALUE
    rb_io_closed(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 0 <= fptr->fd ? Qfalse : Qtrue;
    }
                
    codepoints() click to toggle source

    This is a deprecated alias for each_codepoint.

     
                   static VALUE
    rb_io_codepoints(VALUE io)
    {
        rb_warn("IO#codepoints is deprecated; use #each_codepoint instead");
        if (!rb_block_given_p())
            return rb_enumeratorize(io, ID2SYM(rb_intern("each_codepoint")), 0, 0);
        return rb_io_each_codepoint(io);
    }
                
    each(sep=$/) {|line| block } → ios click to toggle source
    each(limit) {|line| block } → ios
    each(sep, limit) {|line| block } → ios
    each(...) → an_enumerator
    each_line(sep=$/) {|line| block } → ios
    each_line(limit) {|line| block } → ios
    each_line(sep, limit) {|line| block } → ios
    each_line(...) → an_enumerator

    Executes the block for every line in ios, where lines are separated by sep. ios must be opened for reading or an IOError will be raised.

    If no block is given, an enumerator is returned instead.

    f = File.new("testfile")
    f.each {|line| puts "#{f.lineno}: #{line}" }
    

    produces:

    1: This is line one
    2: This is line two
    3: This is line three
    4: And so on...
     
                   static VALUE
    rb_io_each_line(int argc, VALUE *argv, VALUE io)
    {
        VALUE str, rs;
        long limit;
    
        RETURN_ENUMERATOR(io, argc, argv);
        prepare_getline_args(argc, argv, &rs, &limit, io);
        if (limit == 0)
            rb_raise(rb_eArgError, "invalid limit: 0 for each_line");
        while (!NIL_P(str = rb_io_getline_1(rs, limit, io))) {
            rb_yield(str);
        }
        return io;
    }
                
    each_byte {|byte| block } → ios click to toggle source
    each_byte → an_enumerator

    Calls the given block once for each byte (0..255) in ios, passing the byte as an argument. The stream must be opened for reading or an IOError will be raised.

    If no block is given, an enumerator is returned instead.

    f = File.new("testfile")
    checksum = 0
    f.each_byte {|x| checksum ^= x }   #=> #<File:testfile>
    checksum                           #=> 12
    
     
                   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));
                errno = 0;
            }
            rb_io_check_byte_readable(fptr);
            READ_CHECK(fptr);
        } while (io_fillbuf(fptr) >= 0);
        return io;
    }
                
    each_char {|c| block } → ios click to toggle source
    each_char → an_enumerator

    Calls the given block once for each character in ios, passing the character as an argument. The stream must be opened for reading or an IOError will be raised.

    If no block is given, an enumerator is returned instead.

    f = File.new("testfile")
    f.each_char {|c| print c, ' ' }   #=> #<File:testfile>
    
     
                   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| block } → ios click to toggle source
    codepoints {|c| block } → ios
    each_codepoint → an_enumerator
    codepoints → an_enumerator

    Passes the Integer ordinal of each character in ios, passing the codepoint as an argument. The stream must be opened for reading or an IOError will be raised.

    If no block is given, an enumerator is returned instead.

     
                   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));
            }
        }
        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)) {
              invalid:
                rb_raise(rb_eArgError, "invalid byte sequence in %s", rb_enc_name(enc));
            }
            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;
            }
        }
        return io;
    }
                
    each_line(sep=$/) {|line| block } → ios click to toggle source
    each_line(limit) {|line| block } → ios
    each_line(sep, limit) {|line| block } → ios
    each_line(...) → an_enumerator

    Executes the block for every line in ios, where lines are separated by sep. ios must be opened for reading or an IOError will be raised.

    If no block is given, an enumerator is returned instead.

    f = File.new("testfile")
    f.each {|line| puts "#{f.lineno}: #{line}" }
    

    produces:

    1: This is line one
    2: This is line two
    3: This is line three
    4: And so on...
     
                   static VALUE
    rb_io_each_line(int argc, VALUE *argv, VALUE io)
    {
        VALUE str, rs;
        long limit;
    
        RETURN_ENUMERATOR(io, argc, argv);
        prepare_getline_args(argc, argv, &rs, &limit, io);
        if (limit == 0)
            rb_raise(rb_eArgError, "invalid limit: 0 for each_line");
        while (!NIL_P(str = rb_io_getline_1(rs, limit, io))) {
            rb_yield(str);
        }
        return io;
    }
                
    eof → true or false click to toggle source
    eof? → true or false

    Returns true if ios is at end of file that means there are no more data to read. The stream must be opened for reading or an IOError will be raised.

    f = File.new("testfile")
    dummy = f.readlines
    f.eof   #=> true
    

    If ios is a stream such as pipe or socket, IO#eof? 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 blocking
    
    r, w = IO.pipe
    Thread.new { sleep 1; w.puts "a" }
    r.eof?  #=> false after 1 second blocking
    
    r, w = IO.pipe
    r.eof?  # blocks forever
    

    Note that IO#eof? 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).

     
                   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 defined(RUBY_TEST_CRLF_ENVIRONMENT) || defined(_WIN32)
        if (!NEED_READCONV(fptr) && NEED_NEWLINE_DECORATOR_ON_READ(fptr)) {
            return eof(fptr->fd) ? Qtrue : Qfalse;
        }
    #endif
        if (io_fillbuf(fptr) < 0) {
            return Qtrue;
        }
        return Qfalse;
    }
                
    eof? → true or false click to toggle source

    Returns true if ios is at end of file that means there are no more data to read. The stream must be opened for reading or an IOError will be raised.

    f = File.new("testfile")
    dummy = f.readlines
    f.eof   #=> true
    

    If ios is a stream such as pipe or socket, IO#eof? 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 blocking
    
    r, w = IO.pipe
    Thread.new { sleep 1; w.puts "a" }
    r.eof?  #=> false after 1 second blocking
    
    r, w = IO.pipe
    r.eof?  # blocks forever
    

    Note that IO#eof? 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).

     
                   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 defined(RUBY_TEST_CRLF_ENVIRONMENT) || defined(_WIN32)
        if (!NEED_READCONV(fptr) && NEED_NEWLINE_DECORATOR_ON_READ(fptr)) {
            return eof(fptr->fd) ? Qtrue : Qfalse;
        }
    #endif
        if (io_fillbuf(fptr) < 0) {
            return Qtrue;
        }
        return Qfalse;
    }
                
    external_encoding → encoding click to toggle source

    Returns the Encoding object that represents the encoding of the file. If io is in write mode and no encoding is specified, returns nil.

     
                   static VALUE
    rb_io_external_encoding(VALUE io)
    {
        rb_io_t *fptr;
    
        GetOpenFile(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, arg) → integer click to toggle source

    Provides a mechanism for issuing low-level commands to control or query file-oriented I/O streams. Arguments and results are platform dependent. If arg 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). On Unix platforms, see fcntl(2) for details. Not implemented on all platforms.

     
                   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 or nil click to toggle source

    Immediately writes all buffered data in ios to disk.

    If the underlying operating system does not support fdatasync(2), IO#fsync is called instead (which might raise a NotImplementedError).

     
                   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(0);
    
        if ((int)rb_thread_io_blocking_region(nogvl_fdatasync, fptr, fptr->fd) == 0)
            return INT2FIX(0);
    
        /* fall back */
        return rb_io_fsync(io);
    }
                
    fileno → fixnum click to toggle source
    to_i → fixnum

    Returns an integer representing the numeric file descriptor for ios.

    $stdin.fileno    #=> 0
    $stdout.fileno   #=> 1
    
     
                   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);
    }
                
    Also aliased as: to_i
    flush → ios click to toggle source

    Flushes any buffered data within ios to the underlying operating system (note that this is Ruby internal buffering only; the OS may buffer the data as well).

    $stdout.print "no newline"
    $stdout.flush
    

    produces:

    no newline
    
     
                   VALUE
    rb_io_flush(VALUE io)
    {
        return rb_io_flush_raw(io, 1);
    }
                
    fsync → 0 or nil click to toggle source

    Immediately writes all buffered data in ios to disk. Note that fsync differs from using IO#sync=. The latter ensures that data is flushed from Ruby’s buffers, but does not guarantee that the underlying operating system actually writes it to disk.

    NotImplementedError is raised if the underlying operating system does not support fsync(2).

     
                   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(0);
        if ((int)rb_thread_io_blocking_region(nogvl_fsync, fptr, fptr->fd) < 0)
            rb_sys_fail_path(fptr->pathv);
        return INT2FIX(0);
    }
                
    getbyte → fixnum or nil click to toggle source

    Gets the next 8-bit byte (0..255) from ios. Returns nil if called at end of file.

    f = File.new("testfile")
    f.getbyte   #=> 84
    f.getbyte   #=> 104
    
     
                   VALUE
    rb_io_getbyte(VALUE io)
    {
        rb_io_t *fptr;
        int c;
    
        GetOpenFile(io, fptr);
        rb_io_check_byte_readable(fptr);
        READ_CHECK(fptr);
        if (fptr->fd == 0 && (fptr->mode & FMODE_TTY) && RB_TYPE_P(rb_stdout, T_FILE)) {
            rb_io_t *ofp;
            GetOpenFile(rb_stdout, ofp);
            if (ofp->mode & FMODE_TTY) {
                rb_io_flush(rb_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 → string or nil click to toggle source

    Reads a one-character string from ios. Returns nil if called at end of file.

    f = File.new("testfile")
    f.getc   #=> "h"
    f.getc   #=> "e"
    
     
                   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=$/) → string or nil click to toggle source
    gets(limit) → string or nil
    gets(sep, limit) → string or nil

    Reads the next “line” from the I/O stream; lines are separated by sep. A separator of nil reads the entire contents, and a zero-length separator reads the input a paragraph at a time (two successive newlines in the input separate paragraphs). The stream must be opened for reading or an IOError will be raised. The line read in will be returned and also assigned to $_. Returns nil if called at end of file. If the first argument is an integer, or optional second argument is given, the returning string would not be longer than the given value in bytes.

    File.new("testfile").gets   #=> "This is line one\n"
    $_                          #=> "This is line one\n"
    
    File.new("testfile").gets(4)#=> "This"
    

    If IO contains multibyte characters byte then gets(1) returns character entirely:

    # Russian characters take 2 bytes
    File.write("testfile", "\u{442 435 441 442}")
    File.open("testfile") {|f|f.gets(1)} #=> "\u0442"
    File.open("testfile") {|f|f.gets(2)} #=> "\u0442"
    File.open("testfile") {|f|f.gets(3)} #=> "\u0442\u0435"
    File.open("testfile") {|f|f.gets(4)} #=> "\u0442\u0435"
    
     
                   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;
    }
                
    inspect → string click to toggle source

    Return a string describing this IO object.

     
                   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 click to toggle source

    Returns the Encoding of the internal string if conversion is specified. Otherwise returns nil.

     
                   static VALUE
    rb_io_internal_encoding(VALUE io)
    {
        rb_io_t *fptr;
    
        GetOpenFile(io, fptr);
        if (!fptr->encs.enc2) return Qnil;
        return rb_enc_from_encoding(io_read_encoding(fptr));
    }
                
    ioctl(integer_cmd, arg) → integer click to toggle source

    Provides a mechanism for issuing low-level commands to control or query I/O devices. Arguments and results are platform dependent. If arg is a number, its value is passed directly. If it is a string, it is interpreted as a binary sequence of bytes. On Unix platforms, see ioctl(2) for details. Not implemented on all platforms.

     
                   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 → true or false click to toggle source

    Returns true if ios is associated with a terminal device (tty), false otherwise.

    File.new("testfile").isatty   #=> false
    File.new("/dev/tty").isatty   #=> true
    
     
                   static VALUE
    rb_io_isatty(VALUE io)
    {
        rb_io_t *fptr;
    
        GetOpenFile(io, fptr);
        if (isatty(fptr->fd) == 0)
            return Qfalse;
        return Qtrue;
    }
                
    lineno → integer click to toggle source

    Returns the current line number in ios. The stream must be opened for reading. lineno counts the number of times gets is called rather than the number of newlines encountered. The two values will differ if gets is called with a separator other than newline.

    Methods that use $/ like each, lines and readline will also increment lineno.

    See also the $. variable.

    f = File.new("testfile")
    f.lineno   #=> 0
    f.gets     #=> "This is line one\n"
    f.lineno   #=> 1
    f.gets     #=> "This is line two\n"
    f.lineno   #=> 2
    
     
                   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 click to toggle source

    Manually sets the current line number to the given value. $. is updated only on the next read.

    f = File.new("testfile")
    f.gets                     #=> "This is line one\n"
    $.                         #=> 1
    f.lineno = 1000
    f.lineno                   #=> 1000
    $.                         #=> 1         # lineno of last read
    f.gets                     #=> "This is line two\n"
    $.                         #=> 1001      # lineno of last read
    
     
                   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;
    }
                
    lines(*args) click to toggle source

    This is a deprecated alias for each_line.

     
                   static VALUE
    rb_io_lines(int argc, VALUE *argv, VALUE io)
    {
        rb_warn("IO#lines is deprecated; use #each_line instead");
        if (!rb_block_given_p())
            return rb_enumeratorize(io, ID2SYM(rb_intern("each_line")), argc, argv);
        return rb_io_each_line(argc, argv, io);
    }
                
    pid → fixnum click to toggle source

    Returns the process ID of a child process associated with ios. This will be set 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
    

    produces:

    In child, pid is 26209
    In parent, child pid is 26209
     
                   static VALUE
    rb_io_pid(VALUE io)
    {
        rb_io_t *fptr;
    
        GetOpenFile(io, fptr);
        if (!fptr->pid)
            return Qnil;
        return PIDT2NUM(fptr->pid);
    }
                
    pos → integer click to toggle source

    Returns the current offset (in bytes) of ios.

    f = File.new("testfile")
    f.pos    #=> 0
    f.gets   #=> "This is line one\n"
    f.pos    #=> 17
    
     
                   static VALUE
    rb_io_tell(VALUE io)
    {
        rb_io_t *fptr;
        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 = integer → integer click to toggle source

    Seeks to the given position (in bytes) in ios. It is not guaranteed that seeking to the right position when ios is textmode.

    f = File.new("testfile")
    f.pos = 17
    f.gets   #=> "This is line two\n"
    
     
                   static VALUE
    rb_io_set_pos(VALUE io, VALUE offset)
    {
        rb_io_t *fptr;
        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);
    }
                
    printf(format_string [, obj, ...]) → nil click to toggle source

    Formats and writes to ios, converting parameters under control of the format string. See Kernel#sprintf for details.

     
                   VALUE
    rb_io_printf(int argc, const VALUE *argv, VALUE out)
    {
        rb_io_write(out, rb_f_sprintf(argc, argv));
        return Qnil;
    }
                
    putc(obj) → obj click to toggle source

    If obj is Numeric, write the character whose code is the least-significant byte of obj, otherwise write the first byte of the string representation of obj to ios. Note: This method is not safe for use with multi-byte characters as it will truncate them.

    $stdout.putc "A"
    $stdout.putc 65
    

    produces:

    AA
    
     
                   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(obj, ...) → nil click to toggle source

    Writes the given object(s) to ios as with IO#write. Writes a newline after any that do not already end with a newline sequence.

    If called with an array argument, writes each element on a new line. If called without arguments, outputs a single newline. This doesn’t affect $/. ($RS or INPUT_RECORD_SEPARATOR in English.rb)

    $stdout.puts("this", "is", "a", "test")
    

    produces:

    this
    is
    a
    test
    
     
                   VALUE
    rb_io_puts(int argc, const VALUE *argv, VALUE out)
    {
        int i;
        VALUE line;
    
        /* if no argument given, print newline. */
        if (argc == 0) {
            rb_io_write(out, rb_default_rs);
            return Qnil;
        }
        for (i=0; i<argc; i++) {
            if (RB_TYPE_P(argv[i], T_STRING)) {
                line = argv[i];
                goto string;
            }
            if (rb_exec_recursive(io_puts_ary, argv[i], out)) {
                continue;
            }
            line = rb_obj_as_string(argv[i]);
          string:
            rb_io_write(out, line);
            if (RSTRING_LEN(line) == 0 ||
                !str_end_with_asciichar(line, '\n')) {
                rb_io_write(out, rb_default_rs);
            }
        }
    
        return Qnil;
    }
                
    read([length [, outbuf]]) → string, outbuf, or nil click to toggle source

    Reads length bytes from the I/O stream.

    length must be a non-negative integer or nil.

    If length is a positive integer, read tries to read length bytes without any conversion (binary mode). It returns nil if an EOF is encountered before anything can be read. Fewer than length bytes are returned if an EOF is encountered during the read. In the case of an integer length, the resulting string is always in ASCII-8BIT encoding.

    If length is omitted or is nil, it reads until EOF and the encoding conversion is applied, if applicable. A string is returned even if EOF is encountered before any data is read.

    If length is zero, it returns an empty string ("").

    If the optional outbuf argument is present, it must reference a String, which will receive the data. The outbuf will contain only the received data after the method call even if it is not empty at the beginning.

    When this method is called at end of file, it returns nil or "", depending on length: read, read(nil), and read(0) return "", read(positive_integer) returns nil.

    f = File.new("testfile")
    f.read(16)   #=> "This is line one"
    
    # read whole file
    open("file") do |f|
      data = f.read   # This returns a string even if the file is empty.
      # ...
    end
    
    # iterate over fixed length records
    open("fixed-record-file") do |f|
      while record = f.read(256)
        # ...
      end
    end
    
    # iterate over variable length records,
    # each record is prefixed by its 32-bit length
    open("variable-record-file") do |f|
      while len = f.read(4)
        len = len.unpack("N")[0]   # 32-bit length
        record = f.read(len)       # This returns a string even if len is 0.
      end
    end
    

    Note that this method behaves like the fread() function in C. This means it retries to invoke read(2) system calls to read data with the specified length (or until EOF). This behavior is preserved even if ios is in non-blocking mode. (This method is non-blocking flag insensitive as other methods.) If you need the behavior like a single read(2) system call, consider readpartial, read_nonblock, and sysread.

     
                   static VALUE
    io_read(int argc, VALUE *argv, VALUE io)
    {
        rb_io_t *fptr;
        long n, len;
        VALUE length, str;
    #if defined(RUBY_TEST_CRLF_ENVIRONMENT) || defined(_WIN32)
        int previous_mode;
    #endif
    
        rb_scan_args(argc, argv, "02", &length, &str);
    
        if (NIL_P(length)) {
            GetOpenFile(io, fptr);
            rb_io_check_char_readable(fptr);
            return read_all(fptr, remain_size(fptr), str);
        }
        len = NUM2LONG(length);
        if (len < 0) {
            rb_raise(rb_eArgError, "negative length %ld given", len);
        }
    
        io_setstrbuf(&str,len);
    
        GetOpenFile(io, fptr);
        rb_io_check_byte_readable(fptr);
        if (len == 0) {
            io_set_read_length(str, 0);
            return str;
        }
    
        READ_CHECK(fptr);
    #if defined(RUBY_TEST_CRLF_ENVIRONMENT) || defined(_WIN32)
        previous_mode = set_binary_mode_with_seek_cur(fptr);
    #endif
        n = io_fread(str, 0, len, fptr);
        io_set_read_length(str, n);
    #if defined(RUBY_TEST_CRLF_ENVIRONMENT) || defined(_WIN32)
        if (previous_mode == O_TEXT) {
            setmode(fptr->fd, O_TEXT);
        }
    #endif
        if (n == 0) return Qnil;
        OBJ_TAINT(str);
    
        return str;
    }
                
    read_nonblock(maxlen [, options]) → string click to toggle source
    read_nonblock(maxlen, outbuf [, options]) → outbuf

    Reads at most maxlen bytes from ios using the read(2) system call after O_NONBLOCK is set for the underlying file descriptor.

    If the optional outbuf argument is present, it must reference a String, which will receive the data. The outbuf will contain only the received data after the method call even if it is not empty at the beginning.

    #read_nonblock just calls the read(2) system call. It causes all errors the read(2) system call causes: Errno::EWOULDBLOCK, Errno::EINTR, etc. The caller should care such errors.

    If the exception is Errno::EWOULDBLOCK or Errno::EAGAIN, it is extended by IO::WaitReadable. So IO::WaitReadable can be used to rescue the exceptions for retrying read_nonblock.

    #read_nonblock causes EOFError on EOF.

    If the read byte buffer is not empty, #read_nonblock reads from the buffer like readpartial. In this case, the read(2) system call is not called.

    When #read_nonblock raises an exception kind of IO::WaitReadable, #read_nonblock should not be called until io is readable for avoiding busy loop. This can be done as follows.

    # emulates blocking read (readpartial).
    begin
      result = io.read_nonblock(maxlen)
    rescue IO::WaitReadable
      IO.select([io])
      retry
    end
    

    Although #read_nonblock doesn’t raise IO::WaitWritable. OpenSSL::Buffering#read_nonblock can raise IO::WaitWritable. If IO and SSL should be used polymorphically, IO::WaitWritable should be rescued too. See the document of OpenSSL::Buffering#read_nonblock for sample code.

    Note that this method is identical to readpartial except the non-blocking flag is set.

    By specifying `exception: false`, the options hash allows you to indicate that #read_nonblock should not raise an IO::WaitReadable exception, but return the symbol :wait_readable instead.

     
                   # File prelude.rb, line 73
    def read_nonblock(len, buf = nil, exception: true)
      __read_nonblock(len, buf, exception)
    end
                
    readbyte → fixnum click to toggle source

    Reads a byte as with IO#getbyte, but raises an EOFError on end of file.

     
                   static VALUE
    rb_io_readbyte(VALUE io)
    {
        VALUE c = rb_io_getbyte(io);
    
        if (NIL_P(c)) {
            rb_eof_error();
        }
        return c;
    }
                
    readchar → string click to toggle source

    Reads a one-character string from ios. Raises an EOFError on end of file.

    f = File.new("testfile")
    f.readchar   #=> "h"
    f.readchar   #=> "e"
    
     
                   static VALUE
    rb_io_readchar(VALUE io)
    {
        VALUE c = rb_io_getc(io);
    
        if (NIL_P(c)) {
            rb_eof_error();
        }
        return c;
    }
                
    readline(sep=$/) → string click to toggle source
    readline(limit) → string
    readline(sep, limit) → string

    Reads a line as with IO#gets, but raises an EOFError on end of file.

     
                   static VALUE
    rb_io_readline(int argc, VALUE *argv, VALUE io)
    {
        VALUE line = rb_io_gets_m(argc, argv, io);
    
        if (NIL_P(line)) {
            rb_eof_error();
        }
        return line;
    }
                
    readlines(sep=$/) → array click to toggle source
    readlines(limit) → array
    readlines(sep, limit) → array

    Reads all of the lines in ios, and returns them in anArray. Lines are separated by the optional sep. If sep is nil, the rest of the stream is returned as a single record. If the first argument is an integer, or optional second argument is given, the returning string would not be longer than the given value in bytes. The stream must be opened for reading or an IOError will be raised.

    f = File.new("testfile")
    f.readlines[0]   #=> "This is line one\n"
    
     
                   static VALUE
    rb_io_readlines(int argc, VALUE *argv, VALUE io)
    {
        VALUE line, ary, rs;
        long limit;
    
        prepare_getline_args(argc, argv, &rs, &limit, io);
        if (limit == 0)
            rb_raise(rb_eArgError, "invalid limit: 0 for readlines");
        ary = rb_ary_new();
        while (!NIL_P(line = rb_io_getline_1(rs, limit, io))) {
            rb_ary_push(ary, line);
        }
        return ary;
    }
                
    readpartial(maxlen) → string click to toggle source
    readpartial(maxlen, outbuf) → outbuf

    Reads at most maxlen bytes from the I/O stream. It blocks only if ios has no data immediately available. It doesn’t block if some data available.

    If the optional outbuf argument is present, it must reference a String, which will receive the data. The outbuf will contain only the received data after the method call even if it is not empty at the beginning.

    It raises EOFError on end of file.

    readpartial is designed for streams such as pipe, socket, tty, etc. It blocks only when no data immediately available. This means that it blocks only when following all conditions hold.

    • the byte buffer in the IO object is empty.

    • the content of the stream is empty.

    • the stream is not reached to EOF.

    When readpartial blocks, it waits data or EOF on the stream. If some data is reached, readpartial returns with the data. If EOF is reached, readpartial raises EOFError.

    When readpartial doesn’t blocks, it returns or raises immediately. If the byte buffer is not empty, it returns the data in the buffer. Otherwise if the stream has some content, it returns the data in the stream. Otherwise if the stream is reached to EOF, it raises EOFError.

    r, w = IO.pipe           #               buffer          pipe content
    w << "abc"               #               ""              "abc".
    r.readpartial(4096)      #=> "abc"       ""              ""
    r.readpartial(4096)      # blocks because buffer and pipe is empty.
    
    r, w = IO.pipe           #               buffer          pipe content
    w << "abc"               #               ""              "abc"
    w.close                  #               ""              "abc" EOF
    r.readpartial(4096)      #=> "abc"       ""              EOF
    r.readpartial(4096)      # raises EOFError
    
    r, w = IO.pipe           #               buffer          pipe content
    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"     ""              ""
    

    Note that readpartial behaves 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 retry the system call.

    The latter means that readpartial is nonblocking-flag insensitive. It blocks on the situation #sysread causes Errno::EWOULDBLOCK as if the fd is blocking mode.

     
                   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) → ios click to toggle source
    reopen(path, mode_str) → ios

    Reassociates ios with the I/O stream given in other_IO or to a new stream opened on path. This may dynamically change the actual class of this stream.

    f1 = File.new("testfile")
    f2 = File.new("testfile")
    f2.readlines[0]   #=> "This is line one\n"
    f2.reopen(f1)     #=> #<File:testfile>
    f2.readlines[0]   #=> "This is line one\n"
    
     
                   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;
            convconfig_t convconfig;
    
            rb_io_extract_modeenc(&nmode, 0, opt, &oflags, &fmode, &convconfig);
            if (IS_PREP_STDIO(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(0);
        }
        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 click to toggle source

    Positions ios to the beginning of input, resetting lineno to zero.

    f = File.new("testfile")
    f.readline   #=> "This is line one\n"
    f.rewind     #=> 0
    f.lineno     #=> 0
    f.readline   #=> "This is line one\n"
    

    Note that it cannot be used with streams such as pipes, ttys, and sockets.

     
                   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(amount, whence=IO::SEEK_SET) → 0 click to toggle source

    Seeks to a given offset anInteger in the stream according to the value of whence:

    :CUR or IO::SEEK_CUR  | Seeks to _amount_ plus current position
    ----------------------+--------------------------------------------------
    :END or IO::SEEK_END  | Seeks to _amount_ plus end of stream (you
                          | probably want a negative value for _amount_)
    ----------------------+--------------------------------------------------
    :SET or IO::SEEK_SET  | Seeks to the absolute location given by _amount_

    Example:

    f = File.new("testfile")
    f.seek(-13, IO::SEEK_END)   #=> 0
    f.readline                  #=> "And so on...\n"
    
     
                   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) → io click to toggle source
    set_encoding("ext_enc:int_enc") → io
    set_encoding(ext_enc, int_enc) → io
    set_encoding("ext_enc:int_enc", opt) → io
    set_encoding(ext_enc, int_enc, opt) → io

    If single argument is specified, read string from io is tagged with the encoding specified. If encoding is a colon separated two encoding names “A:B”, the read string is converted from encoding A (external encoding) to encoding B (internal encoding), then tagged with B. If two arguments are specified, those must be encoding objects or encoding names, and the first one is the external encoding, and the second one is the internal encoding. If the external encoding and the internal encoding is specified, optional hash argument specify the conversion option.

     
                   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 rb_funcall2(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;
    }
                
    stat → stat click to toggle source

    Returns status information for ios as an object of type File::Stat.

    f = File.new("testfile")
    s = f.stat
    "%o" % s.mode   #=> "100644"
    s.blksize       #=> 4096
    s.atime         #=> Wed Apr 09 08:53:54 CDT 2003
    
     
                   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 → true or false click to toggle source

    Returns the current “sync mode” of ios. When sync mode is true, all output is immediately flushed to the underlying operating system and is not buffered by Ruby internally. See also IO#fsync.

    f = File.new("testfile")
    f.sync   #=> false
    
     
                   static VALUE
    rb_io_sync(VALUE io)
    {
        rb_io_t *fptr;
    
        io = GetWriteIO(io);
        GetOpenFile(io, fptr);
        return (fptr->mode & FMODE_SYNC) ? Qtrue : Qfalse;
    }
                
    sync = boolean → boolean click to toggle source

    Sets the “sync mode” to true or false. When sync mode is true, all output is immediately flushed to the underlying operating system and is not buffered internally. Returns the new state. See also IO#fsync.

    f = File.new("testfile")
    f.sync = true
    

    (produces no output)

     
                   static VALUE
    rb_io_set_sync(VALUE io, VALUE sync)
    {
        rb_io_t *fptr;
    
        io = GetWriteIO(io);
        GetOpenFile(io, fptr);
        if (RTEST(sync)) {
            fptr->mode |= FMODE_SYNC;
        }
        else {
            fptr->mode &= ~FMODE_SYNC;
        }
        return sync;
    }
                
    sysread(maxlen[, outbuf]) → string click to toggle source

    Reads maxlen bytes from ios using a low-level read and returns them as a string. Do not mix with other methods that read from ios or you may get unpredictable results.

    If the optional outbuf argument is present, it must reference a String, which will receive the data. The outbuf will contain only the received data after the method call even if it is not empty at the beginning.

    Raises SystemCallError on error and EOFError at end of file.

    f = File.new("testfile")
    f.sysread(16)   #=> "This is line one"
    
     
                   static VALUE
    rb_io_sysread(int argc, VALUE *argv, VALUE io)
    {
        VALUE len, str;
        rb_io_t *fptr;
        long n, ilen;
        struct read_internal_arg arg;
    
        rb_scan_args(argc, argv, "11", &len, &str);
        ilen = NUM2LONG(len);
    
        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");
        }
    
        /*
         * FIXME: removing rb_thread_wait_fd() here changes sysread semantics
         * on non-blocking IOs.  However, it's still currently possible
         * for sysread to raise Errno::EAGAIN if another thread read()s
         * the IO after we return from rb_thread_wait_fd() but before
         * we call read()
         */
        rb_thread_wait_fd(fptr->fd);
    
        rb_io_check_closed(fptr);
    
        io_setstrbuf(&str, ilen);
        rb_str_locktmp(str);
        arg.fd = fptr->fd;
        arg.str_ptr = RSTRING_PTR(str);
        arg.len = ilen;
        rb_ensure(read_internal_call, (VALUE)&arg, rb_str_unlocktmp, str);
        n = arg.len;
    
        if (n == -1) {
            rb_sys_fail_path(fptr->pathv);
        }
        io_set_read_length(str, n);
        if (n == 0 && ilen > 0) {
            rb_eof_error();
        }
        OBJ_TAINT(str);
    
        return str;
    }
                
    sysseek(offset, whence=IO::SEEK_SET) → integer click to toggle source

    Seeks to a given offset in the stream according to the value of whence (see IO#seek for values of whence). Returns the new offset into the file.

    f = File.new("testfile")
    f.sysseek(-13, IO::SEEK_END)   #=> 53
    f.sysread(10)                  #=> "And so on."
    
     
                   static VALUE
    rb_io_sysseek(int argc, VALUE *argv, VALUE io)
    {
        VALUE offset, ptrname;
        int whence = SEEK_SET;
        rb_io_t *fptr;
        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 == -1 && errno) rb_sys_fail_path(fptr->pathv);
    
        return OFFT2NUM(pos);
    }
                
    syswrite(string) → integer click to toggle source

    Writes the given string to ios using a low-level write. Returns the number of bytes written. Do not mix with other methods that write to ios or you may get unpredictable results. Raises SystemCallError on error.

    f = File.new("out", "w")
    f.syswrite("ABCDEF")   #=> 6
    
     
                   static VALUE
    rb_io_syswrite(VALUE io, VALUE str)
    {
        rb_io_t *fptr;
        long n;
    
        if (!RB_TYPE_P(str, T_STRING))
            str = rb_obj_as_string(str);
    
        io = GetWriteIO(io);
        GetOpenFile(io, fptr);
        rb_io_check_writable(fptr);
    
        str = rb_str_new_frozen(str);
    
        if (fptr->wbuf.len) {
            rb_warn("syswrite for buffered IO");
        }
    
        n = rb_write_internal(fptr->fd, RSTRING_PTR(str), RSTRING_LEN(str));
        RB_GC_GUARD(str);
    
        if (n == -1) rb_sys_fail_path(fptr->pathv);
    
        return LONG2FIX(n);
    }
                
    tell → integer click to toggle source

    Returns the current offset (in bytes) of ios.

    f = File.new("testfile")
    f.pos    #=> 0
    f.gets   #=> "This is line one\n"
    f.pos    #=> 17
    
     
                   static VALUE
    rb_io_tell(VALUE io)
    {
        rb_io_t *fptr;
        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);
    }
                
    to_i() click to toggle source
    Alias for: fileno
    to_io → ios click to toggle source

    Returns ios.

     
                   static VALUE
    rb_io_to_io(VALUE io)
    {
        return io;
    }
                
    tty? → true or false click to toggle source

    Returns true if ios is associated with a terminal device (tty), false otherwise.

    File.new("testfile").isatty   #=> false
    File.new("/dev/tty").isatty   #=> true
    
     
                   static VALUE
    rb_io_isatty(VALUE io)
    {
        rb_io_t *fptr;
    
        GetOpenFile(io, fptr);
        if (isatty(fptr->fd) == 0)
            return Qfalse;
        return Qtrue;
    }
                
    ungetbyte(string) → nil click to toggle source
    ungetbyte(integer) → nil

    Pushes back bytes (passed as a parameter) onto ios, such that a subsequent buffered read will return it. Only one byte may be pushed back before a subsequent read operation (that is, you will be able to read only the last of several bytes that have been pushed back). Has no effect with unbuffered reads (such as IO#sysread).

    f = File.new("testfile")   #=> #<File:testfile>
    b = f.getbyte              #=> 0x38
    f.ungetbyte(b)             #=> nil
    f.getbyte                  #=> 0x38
    
     
                   VALUE
    rb_io_ungetbyte(VALUE io, VALUE b)
    {
        rb_io_t *fptr;
    
        GetOpenFile(io, fptr);
        rb_io_check_byte_readable(fptr);
        if (NIL_P(b)) return Qnil;
        if (FIXNUM_P(b)) {
            char cc = FIX2INT(b);
            b = rb_str_new(&cc, 1);
        }
        else {
            SafeStringValue(b);
        }
        io_ungetbyte(b, fptr);
        return Qnil;
    }
                
    ungetc(string) → nil click to toggle source

    Pushes back one character (passed as a parameter) onto ios, such that a subsequent buffered character read will return it. Only one character may be pushed back before a subsequent read operation (that is, you will be able to read only the last of several characters that have been pushed back). Has no effect with unbuffered reads (such as IO#sysread).

    f = File.new("testfile")   #=> #<File:testfile>
    c = f.getc                 #=> "8"
    f.ungetc(c)                #=> nil
    f.getc                     #=> "8"
    
     
                   VALUE
    rb_io_ungetc(VALUE io, VALUE c)
    {
        rb_io_t *fptr;
        long len;
    
        GetOpenFile(io, fptr);
        rb_io_check_char_readable(fptr);
        if (NIL_P(c)) return Qnil;
        if (FIXNUM_P(c)) {
            c = rb_enc_uint_chr(FIX2UINT(c), io_read_encoding(fptr));
        }
        else if (RB_TYPE_P(c, T_BIGNUM)) {
            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;
    }
                
    write(string) → integer click to toggle source

    Writes the given string to ios. The stream must be opened for writing. If the argument is not a string, it will be converted to a string using to_s. Returns the number of bytes written.

    count = $stdout.write("This is a test\n")
    puts "That was #{count} bytes of data"
    

    produces:

    This is a test
    That was 15 bytes of data
     
                   static VALUE
    io_write_m(VALUE io, VALUE str)
    {
        return io_write(io, str, 0);
    }
                
    write_nonblock(string) → integer click to toggle source
    write_nonblock(string [, options]) → integer

    Writes the given string to ios using the write(2) system call after O_NONBLOCK is set for the underlying file descriptor.

    It returns the number of bytes written.

    #write_nonblock just calls the write(2) system call. It causes all errors the write(2) system call causes: Errno::EWOULDBLOCK, Errno::EINTR, etc. The result may also be smaller than string.length (partial write). The caller should care such errors and partial write.

    If the exception is Errno::EWOULDBLOCK or Errno::EAGAIN, it is extended by IO::WaitWritable. So IO::WaitWritable can be used to rescue the exceptions for retrying write_nonblock.

    # Creates a pipe.
    r, w = IO.pipe
    
    # write_nonblock writes only 65536 bytes and return 65536.
    # (The pipe size is 65536 bytes on this environment.)
    s = "a"  #100000
    p w.write_nonblock(s)     #=> 65536
    
    # write_nonblock cannot write a byte and raise EWOULDBLOCK (EAGAIN).
    p w.write_nonblock("b")   # Resource temporarily unavailable (Errno::EAGAIN)
    

    If the write buffer is not empty, it is flushed at first.

    When #write_nonblock raises an exception kind of IO::WaitWritable, #write_nonblock should not be called until io is writable for avoiding busy loop. This can be done as follows.

    begin
      result = io.write_nonblock(string)
    rescue IO::WaitWritable, Errno::EINTR
      IO.select(nil, [io])
      retry
    end
    

    Note that this doesn’t guarantee to write all data in string. The length written is reported as result and it should be checked later.

    On some platforms such as Windows, #write_nonblock is not supported according to the kind of the IO object. In such cases, #write_nonblock raises Errno::EBADF.

    By specifying `exception: false`, the options hash allows you to indicate that #write_nonblock should not raise an IO::WaitWritable exception, but return the symbol :wait_writable instead.

     
                   # File prelude.rb, line 131
    def write_nonblock(buf, exception: true)
      __write_nonblock(buf, exception)
    end