Class: IO

Inherits:
Object show all
Includes:
Enumerable, File::Constants
Defined in:
io.c

Overview

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 IO.new for these options. See Kernel#open for details of the various command formats described above.

IO.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"

Direct Known Subclasses

File

Defined Under Namespace

Modules: WaitReadable, WaitWritable Classes: EAGAINWaitReadable, EAGAINWaitWritable, EINPROGRESSWaitReadable, EINPROGRESSWaitWritable, EWOULDBLOCKWaitReadable, EWOULDBLOCKWaitWritable

Constant Summary collapse

SEEK_SET =

Set I/O position from the beginning

INT2FIX(SEEK_SET)
SEEK_CUR =

Set I/O position from the current position

INT2FIX(SEEK_CUR)
SEEK_END =

Set I/O position from the end

INT2FIX(SEEK_END)
SEEK_DATA =

Set I/O position to the next location containing data

INT2FIX(SEEK_DATA)
SEEK_HOLE =

Set I/O position to the next hole

INT2FIX(SEEK_HOLE)

Constants included from File::Constants

File::Constants::APPEND, File::Constants::BINARY, File::Constants::CREAT, File::Constants::DIRECT, File::Constants::DSYNC, File::Constants::EXCL, File::Constants::LOCK_EX, File::Constants::LOCK_NB, File::Constants::LOCK_SH, File::Constants::LOCK_UN, File::Constants::NOATIME, File::Constants::NOCTTY, File::Constants::NOFOLLOW, File::Constants::NONBLOCK, File::Constants::NULL, File::Constants::RDONLY, File::Constants::RDWR, File::Constants::RSYNC, File::Constants::SHARE_DELETE, File::Constants::SYNC, File::Constants::TMPFILE, File::Constants::TRUNC, File::Constants::WRONLY

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Enumerable

#all?, #any?, #chain, #chunk, #chunk_while, #collect, #collect_concat, #count, #cycle, #detect, #drop, #drop_while, #each_cons, #each_entry, #each_slice, #each_with_index, #each_with_object, #entries, #filter, #filter_map, #find, #find_all, #find_index, #first, #flat_map, #grep, #grep_v, #group_by, #include?, #inject, #lazy, #map, #max, #max_by, #member?, #min, #min_by, #minmax, #minmax_by, #none?, #one?, #partition, #reduce, #reject, #reverse_each, #select, #slice_after, #slice_before, #slice_when, #sort, #sort_by, #sum, #take, #take_while, #tally, #to_a, #to_h, #uniq, #zip

Constructor Details

#new(fd[, mode][, opt]) ⇒ IO

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 IO.sysopen and IO.for_fd.

IO.new is called by various File and IO opening methods such as IO::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

The exclusive access mode (“x”) can be used together with “w” to ensure the file is created. Errno::EEXIST is raised when it already exists. It may not be supported with all kinds of streams (e.g. pipes).

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.

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



8248
8249
8250
8251
8252
8253
8254
8255
8256
8257
8258
8259
8260
8261
8262
8263
8264
8265
8266
8267
8268
8269
8270
8271
8272
8273
8274
8275
8276
8277
8278
8279
8280
8281
8282
8283
8284
8285
8286
8287
8288
8289
8290
8291
8292
8293
8294
8295
8296
8297
8298
8299
8300
8301
8302
8303
8304
8305
# File 'io.c', line 8248

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) < 0) rb_sys_fail(0);
#endif
    rb_update_max_fd(fd);
#if defined(HAVE_FCNTL) && defined(F_GETFL)
    ofmode = rb_io_oflags_fmode(oflags);
    if (NIL_P(vmode)) {
  fmode = ofmode;
    }
    else if ((~ofmode & fmode) & FMODE_READWRITE) {
  VALUE error = INT2FIX(EINVAL);
  rb_exc_raise(rb_class_new_instance(1, &error, rb_eSystemCallError));
    }
#endif
    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;
}

Class Method Details

.binread(name, [length [, offset]]) ⇒ String

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 "

Returns:



10601
10602
10603
10604
10605
10606
10607
10608
10609
10610
10611
10612
10613
10614
10615
10616
10617
10618
10619
10620
10621
10622
10623
10624
10625
10626
10627
10628
10629
10630
10631
10632
10633
10634
10635
# File 'io.c', line 10601

static VALUE
rb_io_s_binread(int argc, VALUE *argv, VALUE io)
{
    VALUE offset;
    struct foreach_arg arg;
    enum {
  fmode = FMODE_READABLE|FMODE_BINMODE,
  oflags = O_RDONLY
#ifdef O_BINARY
    |O_BINARY
#endif
    };
    convconfig_t convconfig = {NULL, NULL, 0, Qnil};

    rb_scan_args(argc, argv, "12", NULL, NULL, &offset);
    FilePathValue(argv[0]);
    convconfig.enc = rb_ascii8bit_encoding();
    arg.io = rb_io_open_generic(io, argv[0], oflags, fmode, &convconfig, 0);
    if (NIL_P(arg.io)) return Qnil;
    arg.argv = argv+1;
    arg.argc = (argc > 1) ? 1 : 0;
    if (!NIL_P(offset)) {
  struct seek_arg sarg;
  int state = 0;
  sarg.io = arg.io;
  sarg.offset = offset;
  sarg.mode = SEEK_SET;
  rb_protect(seek_before_access, (VALUE)&sarg, &state);
  if (state) {
      rb_io_close(arg.io);
      rb_jump_tag(state);
  }
    }
    return rb_ensure(io_s_read, (VALUE)&arg, rb_io_close, arg.io);
}

.binwrite(name, string, [offset]) ⇒ Integer .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").

Overloads:

  • .binwrite(name, string, [offset]) ⇒ Integer

    Returns:

  • .binwrite(name, string, [offset], open_args) ⇒ Integer

    Returns:



10750
10751
10752
10753
10754
# File 'io.c', line 10750

static VALUE
rb_io_s_binwrite(int argc, VALUE *argv, VALUE io)
{
    return io_s_write(argc, argv, io, 1);
}

.copy_stream(src, dst) ⇒ Object .copy_stream(src, dst, copy_length) ⇒ Object .copy_stream(src, dst, copy_length, src_offset) ⇒ Object

IO.copy_stream copies src to dst. src and dst is either a filename or an IO-like object. IO-like object for src should have #readpartial or #read method. IO-like object for dst should have #write method. (Specialized mechanisms, such as sendfile system call, may be used on appropriate situation.)

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, IO.copy_stream doesn’t move the current file offset.



11651
11652
11653
11654
11655
11656
11657
11658
11659
11660
11661
11662
11663
11664
11665
11666
11667
11668
11669
11670
11671
11672
11673
11674
11675
11676
11677
# File 'io.c', line 11651

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_ensure(copy_stream_body, (VALUE)&st, copy_stream_finalize, (VALUE)&st);

    return OFFT2NUM(st.total);
}

.for_fd(fd, mode[, opt]) ⇒ IO

Synonym for IO.new.

Returns:



8411
8412
8413
8414
8415
8416
8417
# File 'io.c', line 8411

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 = $/[, getline_args, open_args]) {|line| ... } ⇒ nil .foreach(name, limit[, getline_args, open_args]) {|line| ... } ⇒ nil .foreach(name, sep, limit[, getline_args, open_args]) {|line| ... } ⇒ nil .foreach(...) ⇒ Object

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.readlines for details about getline_args. And see also IO.read for details about open_args.

Overloads:

  • .foreach(name, sep = $/[, getline_args, open_args]) {|line| ... } ⇒ nil

    Yields:

    • (line)

    Returns:

    • (nil)
  • .foreach(name, limit[, getline_args, open_args]) {|line| ... } ⇒ nil

    Yields:

    • (line)

    Returns:

    • (nil)
  • .foreach(name, sep, limit[, getline_args, open_args]) {|line| ... } ⇒ nil

    Yields:

    • (line)

    Returns:

    • (nil)


10428
10429
10430
10431
10432
10433
10434
10435
10436
10437
10438
10439
10440
10441
10442
10443
10444
# File 'io.c', line 10428

static VALUE
rb_io_s_foreach(int argc, VALUE *argv, VALUE self)
{
    VALUE opt;
    int orig_argc = argc;
    struct foreach_arg arg;
    struct getline_arg garg;

    argc = rb_scan_args(argc, argv, "13:", NULL, NULL, NULL, NULL, &opt);
    RETURN_ENUMERATOR(self, orig_argc, argv);
    extract_getline_args(argc-1, argv+1, &garg);
    open_key_args(self, argc, argv, opt, &arg);
    if (NIL_P(arg.io)) return Qnil;
    extract_getline_opts(opt, &garg);
    check_getline_args(&garg.rs, &garg.limit, garg.io = arg.io);
    return rb_ensure(io_s_foreach, (VALUE)&garg, rb_io_close, arg.io);
}

.new(*args) ⇒ Object

:nodoc:



8390
8391
8392
8393
8394
8395
8396
8397
8398
8399
8400
# File 'io.c', line 8390

static VALUE
rb_io_s_new(int argc, VALUE *argv, VALUE klass)
{
    if (rb_block_given_p()) {
  VALUE cname = rb_obj_as_string(klass);

  rb_warn("%"PRIsVALUE"::new() does not take block; use %"PRIsVALUE"::open() instead",
    cname, cname);
    }
    return rb_class_new_instance_kw(argc, argv, klass, RB_PASS_CALLED_KEYWORDS);
}

.open(*args) ⇒ Object

call-seq:

IO.open(fd, mode="r" [, opt])                -> io
IO.open(fd, mode="r" [, opt]) {|io| block }  -> obj

With no associated block, IO.open is a synonym for IO.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, IO.open returns the value of the block.

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



7025
7026
7027
7028
7029
7030
7031
7032
7033
7034
7035
# File 'io.c', line 7025

static VALUE
rb_io_s_open(int argc, VALUE *argv, VALUE klass)
{
    VALUE io = rb_class_new_instance_kw(argc, argv, klass, RB_PASS_CALLED_KEYWORDS);

    if (rb_block_given_p()) {
  return rb_ensure(rb_yield, io, io_close, io);
    }

    return io;
}

.pipeArray .pipe(ext_enc) ⇒ Array .pipe("ext_enc: int_enc"[, opt]) ⇒ Array .pipe(ext_enc, int_enc[, opt]) ⇒ Array

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>

Overloads:



10269
10270
10271
10272
10273
10274
10275
10276
10277
10278
10279
10280
10281
10282
10283
10284
10285
10286
10287
10288
10289
10290
10291
10292
10293
10294
10295
10296
10297
10298
10299
10300
10301
10302
10303
10304
10305
10306
10307
10308
10309
10310
10311
10312
10313
10314
10315
10316
10317
10318
10319
10320
10321
10322
10323
10324
10325
10326
10327
10328
10329
10330
10331
10332
10333
10334
10335
10336
10337
10338
10339
10340
10341
10342
10343
10344
10345
10346
10347
10348
10349
10350
10351
10352
# File 'io.c', line 10269

static VALUE
rb_io_s_pipe(int argc, VALUE *argv, VALUE klass)
{
    int pipes[2], state;
    VALUE r, w, args[3], v1, v2;
    VALUE opt;
    rb_io_t *fptr, *fptr2;
    struct io_encoding_set_args ies_args;
    int fmode = 0;
    VALUE ret;

    argc = rb_scan_args(argc, argv, "02:", &v1, &v2, &opt);
    if (rb_pipe(pipes) < 0)
        rb_sys_fail(0);

    args[0] = klass;
    args[1] = INT2NUM(pipes[0]);
    args[2] = INT2FIX(O_RDONLY);
    r = rb_protect(io_new_instance, (VALUE)args, &state);
    if (state) {
  close(pipes[0]);
  close(pipes[1]);
  rb_jump_tag(state);
    }
    GetOpenFile(r, fptr);

    ies_args.fptr = fptr;
    ies_args.v1 = v1;
    ies_args.v2 = v2;
    ies_args.opt = opt;
    rb_protect(io_encoding_set_v, (VALUE)&ies_args, &state);
    if (state) {
  close(pipes[1]);
        io_close(r);
  rb_jump_tag(state);
    }

    args[1] = INT2NUM(pipes[1]);
    args[2] = INT2FIX(O_WRONLY);
    w = rb_protect(io_new_instance, (VALUE)args, &state);
    if (state) {
  close(pipes[1]);
  if (!NIL_P(r)) rb_io_close(r);
  rb_jump_tag(state);
    }
    GetOpenFile(w, fptr2);
    rb_io_synchronized(fptr2);

    extract_binmode(opt, &fmode);

    if ((fmode & FMODE_BINMODE) && v1 == Qnil) {
        rb_io_ascii8bit_binmode(r);
        rb_io_ascii8bit_binmode(w);
    }

#if DEFAULT_TEXTMODE
    if ((fptr->mode & FMODE_TEXTMODE) && (fmode & FMODE_BINMODE)) {
  fptr->mode &= ~FMODE_TEXTMODE;
  setmode(fptr->fd, O_BINARY);
    }
#if 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,], mode = "r"[, opt]) ⇒ IO .popen([env,], mode = "r"[, opt]) {|io| ... } ⇒ Object

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 IO#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 contain 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;

Overloads:

  • .popen([env,], mode = "r"[, opt]) ⇒ IO

    Returns:

  • .popen([env,], mode = "r"[, opt]) {|io| ... } ⇒ Object

    Yields:

    • (io)

    Returns:



6885
6886
6887
6888
6889
6890
6891
6892
6893
6894
6895
6896
6897
6898
6899
6900
6901
6902
6903
6904
6905
6906
6907
6908
6909
6910
6911
6912
6913
6914
6915
6916
6917
6918
6919
6920
6921
6922
6923
6924
6925
6926
6927
6928
6929
6930
6931
6932
6933
6934
6935
6936
6937
6938
6939
6940
6941
6942
6943
6944
6945
6946
6947
6948
6949
6950
# File 'io.c', line 6885

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, FALSE);
  RB_GC_GUARD(tmp);
    }
    else {
  SafeStringValue(pname);
  execarg_obj = Qnil;
  if (!is_popen_fork(pname))
            execarg_obj = rb_execarg_new(1, &pname, TRUE, FALSE);
    }
    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

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.

If name starts with a pipe character ("|"), a subprocess is created in the same way as Kernel#open, and its output is returned.

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

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

:open_args

array

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"

Returns:



10562
10563
10564
10565
10566
10567
10568
10569
10570
10571
10572
10573
10574
10575
10576
10577
10578
10579
10580
10581
10582
10583
10584
10585
# File 'io.c', line 10562

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(io, argc, argv, opt, &arg);
    if (NIL_P(arg.io)) return Qnil;
    if (!NIL_P(offset)) {
  struct seek_arg sarg;
  int state = 0;
  sarg.io = arg.io;
  sarg.offset = offset;
  sarg.mode = SEEK_SET;
  rb_protect(seek_before_access, (VALUE)&sarg, &state);
  if (state) {
      rb_io_close(arg.io);
      rb_jump_tag(state);
  }
  if (arg.argc == 2) arg.argc = 1;
    }
    return rb_ensure(io_s_read, (VALUE)&arg, rb_io_close, arg.io);
}

.readlines(name, sep = $/[, getline_args, open_args]) ⇒ Array .readlines(name, limit[, getline_args, open_args]) ⇒ Array .readlines(name, sep, limit[, getline_args, 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"

b = IO.readlines("testfile", chomp: true)
b[0]   #=> "This is line one"

If the last argument is a hash, it’s the keyword argument to open.

Options for getline

The options hash accepts the following keys:

:chomp

When the optional chomp keyword argument has a true value, \n, \r, and \r\n will be removed from the end of each line.

See also IO.read for details about open_args.

Overloads:

  • .readlines(name, sep = $/[, getline_args, open_args]) ⇒ Array

    Returns:

  • .readlines(name, limit[, getline_args, open_args]) ⇒ Array

    Returns:

  • .readlines(name, sep, limit[, getline_args, open_args]) ⇒ Array

    Returns:



10483
10484
10485
10486
10487
10488
10489
10490
10491
10492
10493
10494
10495
10496
10497
# File 'io.c', line 10483

static VALUE
rb_io_s_readlines(int argc, VALUE *argv, VALUE io)
{
    VALUE opt;
    struct foreach_arg arg;
    struct getline_arg garg;

    argc = rb_scan_args(argc, argv, "13:", NULL, NULL, NULL, NULL, &opt);
    extract_getline_args(argc-1, argv+1, &garg);
    open_key_args(io, argc, argv, opt, &arg);
    if (NIL_P(arg.io)) return Qnil;
    extract_getline_opts(opt, &garg);
    check_getline_args(&garg.rs, &garg.limit, garg.io = arg.io);
    return rb_ensure(io_s_readlines, (VALUE)&garg, rb_io_close, arg.io);
}

.select(read_array[, write_array [, error_array [, timeout]]]) ⇒ Array?

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

Also, the remote side can request SSL renegotiation which forces the local SSL engine to write some data. This means OpenSSL::SSL::SSLSocket#readpartial may invoke #write system call and it can block. In such a situation, OpenSSL::SSL::SSLSocket#read_nonblock raises IO::WaitWritable instead of blocking. So, the caller should wait for ready for writability as above example.

The combination of 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 are writable. IO#write method blocks until given whole string is written. So, IO#write(two or more bytes) can block after writability is notified by IO.select. IO#write_nonblock is required to avoid the blocking.

Blocking write (#write) can be emulated using #write_nonblock and IO.select as follows: IO::WaitReadable should also be rescued for SSL renegotiation in OpenSSL::SSL::SSLSocket.

while 0 < string.bytesize
  begin
    written = io_like.write_nonblock(string)
  rescue IO::WaitReadable
    IO.select([io_like])
    retry
  rescue IO::WaitWritable
    IO.select(nil, [io_like])
    retry
  end
  string = string.byteslice(written..-1)
end

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

Returns:



9546
9547
9548
9549
9550
9551
9552
9553
9554
9555
9556
9557
9558
9559
9560
9561
9562
9563
9564
9565
9566
9567
# File 'io.c', line 9546

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]]) ⇒ Integer

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

IO.sysopen("testfile")   #=> 3

Returns:



7047
7048
7049
7050
7051
7052
7053
7054
7055
7056
7057
7058
7059
7060
7061
7062
7063
7064
7065
7066
7067
7068
7069
7070
7071
7072
# File 'io.c', line 7047

static VALUE
rb_io_s_sysopen(int argc, VALUE *argv, VALUE _)
{
    VALUE fname, vmode, vperm;
    VALUE intmode;
    int oflags, fd;
    mode_t perm;

    rb_scan_args(argc, argv, "12", &fname, &vmode, &vperm);
    FilePathValue(fname);

    if (NIL_P(vmode))
        oflags = O_RDONLY;
    else if (!NIL_P(intmode = rb_check_to_integer(vmode, "to_int")))
        oflags = NUM2INT(intmode);
    else {
  SafeStringValue(vmode);
  oflags = rb_io_modestr_oflags(StringValueCStr(vmode));
    }
    if (NIL_P(vperm)) perm = 0666;
    else              perm = NUM2MODET(vperm);

    RB_GC_GUARD(fname) = rb_str_new4(fname);
    fd = rb_sysopen(fname, oflags, perm);
    return INT2NUM(fd);
}

.try_convert(obj) ⇒ IO?

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>

Returns:

  • (IO, nil)


788
789
790
791
792
# File 'io.c', line 788

static VALUE
rb_io_s_try_convert(VALUE dummy, VALUE io)
{
    return rb_io_check_io(io);
}

.write(name, string[, offset]) ⇒ Integer .write(name, string[, offset][, opt]) ⇒ Integer

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 in write mode, the file is truncated. Otherwise, it is not truncated.

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"

If the last argument is a hash, it specifies options for the internal open(). It accepts the following keys:

:encoding

string or encoding

Specifies the encoding of the read string. See Encoding.aliases for possible encodings.

:mode

string or integer

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

:perm

integer

Specifies the perm argument for open().

:open_args

array

Specifies arguments for open() as an array. This key can not be used in combination with other keys.

Overloads:



10735
10736
10737
10738
10739
# File 'io.c', line 10735

static VALUE
rb_io_s_write(int argc, VALUE *argv, VALUE io)
{
    return io_s_write(argc, argv, io, 0);
}

Instance Method Details

#<<(obj) ⇒ IO

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

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

produces:

Hello world!

Returns:



1842
1843
1844
1845
1846
1847
# File 'io.c', line 1842

VALUE
rb_io_addstr(VALUE io, VALUE str)
{
    rb_io_write(io, str);
    return io;
}

#advise(advice, offset = 0, len = 0) ⇒ nil

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.

Returns:

  • (nil)


9382
9383
9384
9385
9386
9387
9388
9389
9390
9391
9392
9393
9394
9395
9396
9397
9398
9399
9400
9401
9402
9403
9404
# File 'io.c', line 9382

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) ⇒ Boolean

Sets auto-close flag.

f = open("/dev/null")
IO.for_fd(f.fileno)
# ...
f.gets # may cause Errno::EBADF

f = open("/dev/null")
IO.for_fd(f.fileno).autoclose = false
# ...
f.gets # won't cause Errno::EBADF

Returns:

  • (Boolean)


8452
8453
8454
8455
8456
8457
8458
8459
8460
8461
8462
# File 'io.c', line 8452

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 autoclose;
}

#autoclose?Boolean

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

Returns:

  • (Boolean)


8427
8428
8429
8430
8431
8432
8433
# File 'io.c', line 8427

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

#binmodeIO

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

Returns:



5402
5403
5404
5405
5406
5407
5408
5409
5410
5411
5412
5413
# File 'io.c', line 5402

static VALUE
rb_io_binmode_m(VALUE io)
{
    VALUE write_io;

    rb_io_ascii8bit_binmode(io);

    write_io = GetWriteIO(io);
    if (write_io != io)
        rb_io_ascii8bit_binmode(write_io);
    return io;
}

#binmode?Boolean

Returns true if ios is binmode.

Returns:

  • (Boolean)


5421
5422
5423
5424
5425
5426
5427
# File 'io.c', line 5421

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

#bytesObject

This is a deprecated alias for #each_byte.



3861
3862
3863
3864
3865
3866
3867
3868
# File 'io.c', line 3861

static VALUE
rb_io_bytes(VALUE io)
{
    rb_warn_deprecated("IO#bytes", "#each_byte");
    if (!rb_block_given_p())
  return rb_enumeratorize(io, ID2SYM(rb_intern("each_byte")), 0, 0);
    return rb_io_each_byte(io);
}

#charsObject

This is a deprecated alias for #each_char.



4015
4016
4017
4018
4019
4020
4021
4022
# File 'io.c', line 4015

static VALUE
rb_io_chars(VALUE io)
{
    rb_warn_deprecated("IO#chars", "#each_char");
    if (!rb_block_given_p())
  return rb_enumeratorize(io, ID2SYM(rb_intern("each_char")), 0, 0);
    return rb_io_each_char(io);
}

#closenil

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.

Returns:

  • (nil)


4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
# File 'io.c', line 4842

static VALUE
rb_io_close_m(VALUE io)
{
    rb_io_t *fptr = rb_io_get_fptr(io);
    if (fptr->fd < 0) {
        return Qnil;
    }
    rb_io_close(io);
    return Qnil;
}

#close_on_exec=(bool) ⇒ Boolean

Sets a close-on-exec flag.

f = 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.

Returns:

  • (Boolean)


4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
# File 'io.c', line 4445

static VALUE
rb_io_set_close_on_exec(VALUE io, VALUE arg)
{
    int flag = RTEST(arg) ? FD_CLOEXEC : 0;
    rb_io_t *fptr;
    VALUE write_io;
    int fd, ret;

    write_io = GetWriteIO(io);
    if (io != write_io) {
        GetOpenFile(write_io, fptr);
        if (fptr && 0 <= (fd = fptr->fd)) {
            if ((ret = fcntl(fptr->fd, F_GETFD)) == -1) rb_sys_fail_path(fptr->pathv);
            if ((ret & FD_CLOEXEC) != flag) {
                ret = (ret & ~FD_CLOEXEC) | flag;
                ret = fcntl(fd, F_SETFD, ret);
                if (ret != 0) rb_sys_fail_path(fptr->pathv);
            }
        }

    }

    GetOpenFile(io, fptr);
    if (fptr && 0 <= (fd = fptr->fd)) {
        if ((ret = fcntl(fd, F_GETFD)) == -1) rb_sys_fail_path(fptr->pathv);
        if ((ret & FD_CLOEXEC) != flag) {
            ret = (ret & ~FD_CLOEXEC) | flag;
            ret = fcntl(fd, F_SETFD, ret);
            if (ret != 0) rb_sys_fail_path(fptr->pathv);
        }
    }
    return Qnil;
}

#close_on_exec?Boolean

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

Returns:

  • (Boolean)


4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
# File 'io.c', line 4397

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_readnil

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

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

Returns:

  • (nil)


4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
# File 'io.c', line 4941

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_writenil

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

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

Returns:

  • (nil)


5003
5004
5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
5015
5016
5017
5018
5019
5020
5021
5022
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033
5034
# File 'io.c', line 5003

static VALUE
rb_io_close_write(VALUE io)
{
    rb_io_t *fptr;
    VALUE write_io;

    write_io = GetWriteIO(io);
    fptr = rb_io_get_fptr(rb_io_taint_check(write_io));
    if (fptr->fd < 0) return Qnil;
    if (is_socket(fptr->fd, fptr->pathv)) {
#ifndef SHUT_WR
# define SHUT_WR 1
#endif
        if (shutdown(fptr->fd, SHUT_WR) < 0)
            rb_sys_fail_path(fptr->pathv);
        fptr->mode &= ~FMODE_WRITABLE;
        if (!(fptr->mode & FMODE_READABLE))
      return rb_io_close(write_io);
        return Qnil;
    }

    if ((fptr->mode & (FMODE_DUPLEX|FMODE_READABLE)) == FMODE_READABLE) {
  rb_raise(rb_eIOError, "closing non-duplex IO for writing");
    }

    if (io != write_io) {
  fptr = rb_io_get_fptr(rb_io_taint_check(io));
  fptr->tied_io_for_writing = 0;
    }
    rb_io_close(write_io);
    return Qnil;
}

#closed?Boolean

Returns true if 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

Returns:

  • (Boolean)


4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
# File 'io.c', line 4902

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

#codepointsObject

This is a deprecated alias for #each_codepoint.



4143
4144
4145
4146
4147
4148
4149
4150
# File 'io.c', line 4143

static VALUE
rb_io_codepoints(VALUE io)
{
    rb_warn_deprecated("IO#codepoints", "#each_codepoint");
    if (!rb_block_given_p())
  return rb_enumeratorize(io, ID2SYM(rb_intern("each_codepoint")), 0, 0);
    return rb_io_each_codepoint(io);
}

#each(sep = $/[, getline_args]) {|line| ... } ⇒ IO #each(limit[, getline_args]) {|line| ... } ⇒ IO #each(sep, limit[, getline_args]) {|line| ... } ⇒ IO #each(...) ⇒ Object

ios.each_line(sep=$/ [, getline_args]) {|line| block } -> ios

ios.each_line(limit [, getline_args])      {|line| block } -> ios
ios.each_line(sep, limit [, getline_args]) {|line| block } -> ios
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...

See IO.readlines for details about getline_args.

Overloads:

  • #each(sep = $/[, getline_args]) {|line| ... } ⇒ IO

    Yields:

    • (line)

    Returns:

  • #each(limit[, getline_args]) {|line| ... } ⇒ IO

    Yields:

    • (line)

    Returns:

  • #each(sep, limit[, getline_args]) {|line| ... } ⇒ IO

    Yields:

    • (line)

    Returns:



3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
# File 'io.c', line 3790

static VALUE
rb_io_each_line(int argc, VALUE *argv, VALUE io)
{
    VALUE str;
    struct getline_arg args;

    RETURN_ENUMERATOR(io, argc, argv);
    prepare_getline_args(argc, argv, &args, io);
    if (args.limit == 0)
  rb_raise(rb_eArgError, "invalid limit: 0 for each_line");
    while (!NIL_P(str = rb_io_getline_1(args.rs, args.limit, args.chomp, io))) {
  rb_yield(str);
    }
    return io;
}

#each_byte {|byte| ... } ⇒ IO #each_byteObject

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

Overloads:

  • #each_byte {|byte| ... } ⇒ IO

    Yields:

    • (byte)

    Returns:



3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
# File 'io.c', line 3836

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| ... } ⇒ IO #each_charObject

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>

Overloads:

  • #each_char {|c| ... } ⇒ IO

    Yields:

    • (c)

    Returns:



3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
# File 'io.c', line 3992

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| ... } ⇒ IO #codepoints {|c| ... } ⇒ IO #each_codepointObject #codepointsObject

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.

Overloads:

  • #each_codepoint {|c| ... } ⇒ IO

    Yields:

    • (c)

    Returns:

  • #codepoints {|c| ... } ⇒ IO

    Yields:

    • (c)

    Returns:



4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
# File 'io.c', line 4040

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(sep = $/[, getline_args]) {|line| ... } ⇒ IO #each(limit[, getline_args]) {|line| ... } ⇒ IO #each(sep, limit[, getline_args]) {|line| ... } ⇒ IO #each(...) ⇒ Object

ios.each_line(sep=$/ [, getline_args]) {|line| block } -> ios

ios.each_line(limit [, getline_args])      {|line| block } -> ios
ios.each_line(sep, limit [, getline_args]) {|line| block } -> ios
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...

See IO.readlines for details about getline_args.

Overloads:

  • #each(sep = $/[, getline_args]) {|line| ... } ⇒ IO

    Yields:

    • (line)

    Returns:

  • #each(limit[, getline_args]) {|line| ... } ⇒ IO

    Yields:

    • (line)

    Returns:

  • #each(sep, limit[, getline_args]) {|line| ... } ⇒ IO

    Yields:

    • (line)

    Returns:



3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
# File 'io.c', line 3790

static VALUE
rb_io_each_line(int argc, VALUE *argv, VALUE io)
{
    VALUE str;
    struct getline_arg args;

    RETURN_ENUMERATOR(io, argc, argv);
    prepare_getline_args(argc, argv, &args, io);
    if (args.limit == 0)
  rb_raise(rb_eArgError, "invalid limit: 0 for each_line");
    while (!NIL_P(str = rb_io_getline_1(args.rs, args.limit, args.chomp, io))) {
  rb_yield(str);
    }
    return io;
}

#eofBoolean #eof?Boolean

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

Overloads:

  • #eofBoolean

    Returns:

    • (Boolean)
  • #eof?Boolean

    Returns:

    • (Boolean)


2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
# File 'io.c', line 2148

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

#eofBoolean #eof?Boolean

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

Overloads:

  • #eofBoolean

    Returns:

    • (Boolean)
  • #eof?Boolean

    Returns:

    • (Boolean)


2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
# File 'io.c', line 2148

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_encodingEncoding

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

Returns:



11687
11688
11689
11690
11691
11692
11693
11694
11695
11696
11697
11698
11699
11700
11701
11702
# File 'io.c', line 11687

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

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.

Returns:



9968
9969
9970
9971
9972
9973
9974
9975
# File 'io.c', line 9968

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);
}

#fdatasync0?

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

Returns:

  • (0, nil)


2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
# File 'io.c', line 2286

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);
}

#filenoInteger #to_iInteger Also known as: to_i

Returns an integer representing the numeric file descriptor for ios.

$stdin.fileno    #=> 0
$stdout.fileno   #=> 1

Overloads:



2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
# File 'io.c', line 2319

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);
}

#flushIO

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

Returns:



1902
1903
1904
1905
1906
# File 'io.c', line 1902

VALUE
rb_io_flush(VALUE io)
{
    return rb_io_flush_raw(io, 1);
}

#fsync0?

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

Returns:

  • (0, nil)


2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
# File 'io.c', line 2237

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);
}

#getbyteInteger?

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

Returns:



4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
# File 'io.c', line 4214

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);
}

#getcString?

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"

Returns:



4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
# File 'io.c', line 4165

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 = $/[, getline_args]) ⇒ String? #gets(limit[, getline_args]) ⇒ String? #gets(sep, limit[, getline_args]) ⇒ String?

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"

Overloads:

  • #gets(sep = $/[, getline_args]) ⇒ String?

    Returns:

  • #gets(limit[, getline_args]) ⇒ String?

    Returns:

  • #gets(sep, limit[, getline_args]) ⇒ String?

    Returns:



3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
# File 'io.c', line 3619

static VALUE
rb_io_gets_m(int argc, VALUE *argv, VALUE io)
{
    VALUE str;

    str = rb_io_getline(argc, argv, io);
    rb_lastline_set(str);

    return str;
}

#initialize_copy(io) ⇒ Object

:nodoc:



7454
7455
7456
7457
7458
7459
7460
7461
7462
7463
7464
7465
7466
7467
7468
7469
7470
7471
7472
7473
7474
7475
7476
7477
7478
7479
7480
7481
7482
7483
7484
7485
7486
7487
7488
7489
7490
7491
7492
7493
7494
# File 'io.c', line 7454

static VALUE
rb_io_init_copy(VALUE dest, VALUE io)
{
    rb_io_t *fptr, *orig;
    int fd;
    VALUE write_io;
    off_t pos;

    io = rb_io_get_io(io);
    if (!OBJ_INIT_COPY(dest, io)) return dest;
    GetOpenFile(io, orig);
    MakeOpenFile(dest, fptr);

    rb_io_flush(io);

    /* copy rb_io_t structure */
    fptr->mode = orig->mode & ~FMODE_PREP;
    fptr->encs = orig->encs;
    fptr->pid = orig->pid;
    fptr->lineno = orig->lineno;
    if (!NIL_P(orig->pathv)) fptr->pathv = orig->pathv;
    fptr_copy_finalizer(fptr, orig);

    fd = ruby_dup(orig->fd);
    fptr->fd = fd;
    pos = io_tell(orig);
    if (0 <= pos)
        io_seek(fptr, pos, SEEK_SET);
    if (fptr->mode & FMODE_BINMODE) {
  rb_io_binmode(dest);
    }

    write_io = GetWriteIO(io);
    if (io != write_io) {
        write_io = rb_obj_dup(write_io);
        fptr->tied_io_for_writing = write_io;
        rb_ivar_set(dest, rb_intern("@tied_io_for_writing"), write_io);
    }

    return dest;
}

#inspectString

Return a string describing this IO object.

Returns:



2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
# File 'io.c', line 2370

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_encodingEncoding

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

Returns:



11712
11713
11714
11715
11716
11717
11718
11719
11720
# File 'io.c', line 11712

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

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.

Returns:



9874
9875
9876
9877
9878
9879
9880
9881
# File 'io.c', line 9874

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);
}

#isattyBoolean #tty?Boolean

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

File.new("testfile").isatty   #=> false
File.new("/dev/tty").isatty   #=> true

Overloads:

  • #isattyBoolean

    Returns:

    • (Boolean)
  • #tty?Boolean

    Returns:

    • (Boolean)


4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
# File 'io.c', line 4371

static VALUE
rb_io_isatty(VALUE io)
{
    rb_io_t *fptr;

    GetOpenFile(io, fptr);
    if (isatty(fptr->fd) == 0)
  return Qfalse;
    return Qtrue;
}

#linenoInteger

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

Returns:



3652
3653
3654
3655
3656
3657
3658
3659
3660
# File 'io.c', line 3652

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

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

Returns:



3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
# File 'io.c', line 3679

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) ⇒ Object

This is a deprecated alias for #each_line.



3810
3811
3812
3813
3814
3815
3816
3817
# File 'io.c', line 3810

static VALUE
rb_io_lines(int argc, VALUE *argv, VALUE io)
{
    rb_warn_deprecated("IO#lines", "#each_line");
    if (!rb_block_given_p())
  return rb_enumeratorize(io, ID2SYM(rb_intern("each_line")), argc, argv);
    return rb_io_each_line(argc, argv, io);
}

#pidInteger

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

Returns:



2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
# File 'io.c', line 2351

static VALUE
rb_io_pid(VALUE io)
{
    rb_io_t *fptr;

    GetOpenFile(io, fptr);
    if (!fptr->pid)
  return Qnil;
    return PIDT2NUM(fptr->pid);
}

#posInteger #tellInteger

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

Overloads:



1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
# File 'io.c', line 1921

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

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"

Returns:



2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
# File 'io.c', line 2015

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);
}

#pread(maxlen, offset[, outbuf]) ⇒ String

Reads maxlen bytes from ios using the pread system call and returns them as a string without modifying the underlying descriptor offset. This is advantageous compared to combining IO#seek and IO#read in that it is atomic, allowing multiple threads/process to share the same IO object for reading the file at various locations. This bypasses any userspace buffering of the IO layer. If the optional outbuf argument is present, it must reference a String, which will receive the data. Raises SystemCallError on error, EOFError at end of file and NotImplementedError if platform does not implement the system call.

File.write("testfile", "This is line one\nThis is line two\n")
File.open("testfile") do |f|
  p f.read           # => "This is line one\nThis is line two\n"
  p f.pread(12, 0)   # => "This is line"
  p f.pread(9, 8)    # => "line one\n"
end

Returns:



5233
5234
5235
5236
5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
# File 'io.c', line 5233

static VALUE
rb_io_pread(int argc, VALUE *argv, VALUE io)
{
    VALUE len, offset, str;
    rb_io_t *fptr;
    ssize_t n;
    struct prdwr_internal_arg arg;
    int shrinkable;

    rb_scan_args(argc, argv, "21", &len, &offset, &str);
    arg.count = NUM2SIZET(len);
    arg.offset = NUM2OFFT(offset);

    shrinkable = io_setstrbuf(&str, (long)arg.count);
    if (arg.count == 0) return str;
    arg.buf = RSTRING_PTR(str);

    GetOpenFile(io, fptr);
    rb_io_check_byte_readable(fptr);

    arg.fd = fptr->fd;
    rb_io_check_closed(fptr);

    rb_str_locktmp(str);
    n = (ssize_t)rb_ensure(pread_internal_call, (VALUE)&arg, rb_str_unlocktmp, str);

    if (n < 0) {
  rb_sys_fail_path(fptr->pathv);
    }
    io_set_read_length(str, n, shrinkable);
    if (n == 0 && arg.count > 0) {
  rb_eof_error();
    }

    return str;
}

Writes the given object(s) to ios. Returns nil.

The stream must be opened for writing. Each given object that isn’t a string will be converted by calling its to_s method. When called without arguments, prints the contents of $_.

If the output field separator ($,) is not nil, it is inserted between objects. If the output record separator ($\) is not nil, it is appended to the output.

$stdout.print("This is ", 100, " percent.\n")

produces:

This is 100 percent.

Overloads:

  • #printnil

    Returns:

    • (nil)
  • #print(obj, ...) ⇒ nil

    Returns:

    • (nil)


7575
7576
7577
7578
7579
7580
7581
7582
7583
7584
7585
7586
7587
7588
7589
7590
7591
7592
7593
7594
7595
7596
7597
7598
# File 'io.c', line 7575

VALUE
rb_io_print(int argc, const VALUE *argv, VALUE out)
{
    int i;
    VALUE line;

    /* if no argument given, print `$_' */
    if (argc == 0) {
  argc = 1;
  line = rb_lastline_get();
  argv = &line;
    }
    for (i=0; i<argc; i++) {
  if (!NIL_P(rb_output_fs) && i>0) {
      rb_io_write(out, rb_output_fs);
  }
  rb_io_write(out, argv[i]);
    }
    if (argc > 0 && !NIL_P(rb_output_rs)) {
  rb_io_write(out, rb_output_rs);
    }

    return Qnil;
}

#printf(format_string[, obj, ...]) ⇒ nil

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

Returns:

  • (nil)


7504
7505
7506
7507
7508
7509
# File 'io.c', line 7504

VALUE
rb_io_printf(int argc, const VALUE *argv, VALUE out)
{
    rb_io_write(out, rb_f_sprintf(argc, argv));
    return Qnil;
}

#putc(obj) ⇒ Object

If obj is Numeric, write the character whose code is the least-significant byte of obj. If obj is String, write the first character of obj to ios. Otherwise, raise TypeError.

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

produces:

AA

Returns:



7647
7648
7649
7650
7651
7652
7653
7654
7655
7656
7657
7658
7659
7660
# File 'io.c', line 7647

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

Writes the given object(s) to ios. Writes a newline after any that do not already end with a newline sequence. Returns nil.

The stream must be opened for writing. If called with an array argument, writes each element on a new line. Each given object that isn’t a string or array will be converted by calling its to_s method. If called without arguments, outputs a single newline.

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

produces:

this
is
a
test

Note that puts always uses newlines and is not affected by the output record separator ($\).

Returns:

  • (nil)


7746
7747
7748
7749
7750
7751
7752
7753
7754
7755
7756
7757
7758
7759
7760
7761
7762
7763
7764
7765
7766
7767
7768
7769
7770
7771
7772
7773
7774
7775
7776
7777
# File 'io.c', line 7746

VALUE
rb_io_puts(int argc, const VALUE *argv, VALUE out)
{
    int i, n;
    VALUE line, args[2];

    /* 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:
  n = 0;
  args[n++] = line;
  if (RSTRING_LEN(line) == 0 ||
            !rb_str_end_with_asciichar(line, '\n')) {
      args[n++] = rb_default_rs;
  }
  rb_io_writev(out, n, args);
    }

    return Qnil;
}

#pwrite(string, offset) ⇒ Integer

Writes the given string to ios at offset using pwrite() system call. This is advantageous to combining IO#seek and IO#write in that it is atomic, allowing multiple threads/process to share the same IO object for reading the file at various locations. This bypasses any userspace buffering of the IO layer. Returns the number of bytes written. Raises SystemCallError on error and NotImplementedError if platform does not implement the system call.

File.open("out", "w") do |f|
  f.pwrite("ABCDEF", 3)   #=> 6
end

File.read("out")          #=> "\u0000\u0000\u0000ABCDEF"

Returns:



5301
5302
5303
5304
5305
5306
5307
5308
5309
5310
5311
5312
5313
5314
5315
5316
5317
5318
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
# File 'io.c', line 5301

static VALUE
rb_io_pwrite(VALUE io, VALUE str, VALUE offset)
{
    rb_io_t *fptr;
    ssize_t n;
    struct prdwr_internal_arg arg;
    VALUE tmp;

    if (!RB_TYPE_P(str, T_STRING))
  str = rb_obj_as_string(str);

    arg.offset = NUM2OFFT(offset);

    io = GetWriteIO(io);
    GetOpenFile(io, fptr);
    rb_io_check_writable(fptr);
    arg.fd = fptr->fd;

    tmp = rb_str_tmp_frozen_acquire(str);
    arg.buf = RSTRING_PTR(tmp);
    arg.count = (size_t)RSTRING_LEN(tmp);

    n = (ssize_t)rb_thread_io_blocking_region(internal_pwrite_func, &arg, fptr->fd);
    if (n < 0) rb_sys_fail_path(fptr->pathv);
    rb_str_tmp_frozen_release(str, tmp);

    return SSIZET2NUM(n);
}

#read([length [, outbuf]]) ⇒ String?

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.

Returns:



3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
# File 'io.c', line 3105

static VALUE
io_read(int argc, VALUE *argv, VALUE io)
{
    rb_io_t *fptr;
    long n, len;
    VALUE length, str;
    int shrinkable;
#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);
    }

    shrinkable = io_setstrbuf(&str,len);

    GetOpenFile(io, fptr);
    rb_io_check_byte_readable(fptr);
    if (len == 0) {
  io_set_read_length(str, 0, shrinkable);
  return str;
    }

    READ_CHECK(fptr);
#if 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, shrinkable);
#if defined(RUBY_TEST_CRLF_ENVIRONMENT) || defined(_WIN32)
    if (previous_mode == O_TEXT) {
  setmode(fptr->fd, O_TEXT);
    }
#endif
    if (n == 0) return Qnil;

    return str;
}

#readbyteInteger

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

Returns:



4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
# File 'io.c', line 4247

static VALUE
rb_io_readbyte(VALUE io)
{
    VALUE c = rb_io_getbyte(io);

    if (NIL_P(c)) {
  rb_eof_error();
    }
    return c;
}

#readcharString

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

f = File.new("testfile")
f.readchar   #=> "h"
f.readchar   #=> "e"

Returns:



4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
# File 'io.c', line 4191

static VALUE
rb_io_readchar(VALUE io)
{
    VALUE c = rb_io_getc(io);

    if (NIL_P(c)) {
  rb_eof_error();
    }
    return c;
}

#readline(sep = $/[, getline_args]) ⇒ String #readline(limit[, getline_args]) ⇒ String #readline(sep, limit[, getline_args]) ⇒ String

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

Overloads:

  • #readline(sep = $/[, getline_args]) ⇒ String

    Returns:

  • #readline(limit[, getline_args]) ⇒ String

    Returns:

  • #readline(sep, limit[, getline_args]) ⇒ String

    Returns:



3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
# File 'io.c', line 3699

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 = $/[, getline_args]) ⇒ Array #readlines(limit[, getline_args]) ⇒ Array #readlines(sep, limit[, getline_args]) ⇒ Array

Reads all of the lines in ios, and returns them in an array. 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 an 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"

f = File.new("testfile", chomp: true)
f.readlines[0]   #=> "This is line one"

See IO.readlines for details about getline_args.

Overloads:

  • #readlines(sep = $/[, getline_args]) ⇒ Array

    Returns:

  • #readlines(limit[, getline_args]) ⇒ Array

    Returns:

  • #readlines(sep, limit[, getline_args]) ⇒ Array

    Returns:



3736
3737
3738
3739
3740
3741
3742
3743
# File 'io.c', line 3736

static VALUE
rb_io_readlines(int argc, VALUE *argv, VALUE io)
{
    struct getline_arg args;

    prepare_getline_args(argc, argv, &args, io);
    return io_readlines(&args, io);
}

#readpartial(maxlen) ⇒ String #readpartial(maxlen, outbuf) ⇒ Object

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 IO#sysread causes Errno::EWOULDBLOCK as if the fd is blocking mode.

Overloads:



2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
# File 'io.c', line 2929

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) ⇒ IO #reopen(path, mode[, opt]) ⇒ IO

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. The mode and opt parameters accept the same values as IO.open.

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"

Overloads:

  • #reopen(other_IO) ⇒ IO

    Returns:

  • #reopen(path, mode[, opt]) ⇒ IO

    Returns:



7365
7366
7367
7368
7369
7370
7371
7372
7373
7374
7375
7376
7377
7378
7379
7380
7381
7382
7383
7384
7385
7386
7387
7388
7389
7390
7391
7392
7393
7394
7395
7396
7397
7398
7399
7400
7401
7402
7403
7404
7405
7406
7407
7408
7409
7410
7411
7412
7413
7414
7415
7416
7417
7418
7419
7420
7421
7422
7423
7424
7425
7426
7427
7428
7429
7430
7431
7432
7433
7434
7435
7436
7437
7438
7439
7440
7441
7442
7443
7444
7445
7446
7447
7448
7449
7450
7451
# File 'io.c', line 7365

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

#rewind0

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.

Returns:

  • (0)


2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
# File 'io.c', line 2047

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

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"

Returns:

  • (0)


1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
# File 'io.c', line 1989

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

Overloads:

  • #set_encoding(ext_enc) ⇒ IO

    Returns:

  • #set_encoding("ext_enc: int_enc") ⇒ IO

    Returns:

  • #set_encoding(ext_enc, int_enc) ⇒ IO

    Returns:

  • #set_encoding("ext_enc: int_enc", opt) ⇒ IO

    Returns:

  • #set_encoding(ext_enc, int_enc, opt) ⇒ IO

    Returns:



11741
11742
11743
11744
11745
11746
11747
11748
11749
11750
11751
11752
11753
11754
11755
# File 'io.c', line 11741

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_funcallv(io, id_set_encoding, argc, argv);
    }

    argc = rb_scan_args(argc, argv, "11:", &v1, &v2, &opt);
    GetOpenFile(io, fptr);
    io_encoding_set(fptr, v1, v2, opt);
    return io;
}

#set_encoding_by_bomEncoding?

Checks if ios starts with a BOM, and then consumes it and sets the external encoding. Returns the result encoding if found, or nil. If ios is not binmode or its encoding has been set already, an exception will be raised.

File.write("bom.txt", "\u{FEFF}abc")
ios = File.open("bom.txt", "rb")
ios.set_encoding_by_bom    #=>  #<Encoding:UTF-8>

File.write("nobom.txt", "abc")
ios = File.open("nobom.txt", "rb")
ios.set_encoding_by_bom    #=>  nil

Returns:



8325
8326
8327
8328
8329
8330
8331
8332
8333
8334
8335
8336
8337
8338
8339
8340
8341
8342
8343
# File 'io.c', line 8325

static VALUE
rb_io_set_encoding_by_bom(VALUE io)
{
    rb_io_t *fptr;

    GetOpenFile(io, fptr);
    if (!(fptr->mode & FMODE_BINMODE)) {
        rb_raise(rb_eArgError, "ASCII incompatible encoding needs binmode");
    }
    if (fptr->encs.enc2) {
        rb_raise(rb_eArgError, "encoding conversion is set");
    }
    else if (fptr->encs.enc && fptr->encs.enc != rb_ascii8bit_encoding()) {
        rb_raise(rb_eArgError, "encoding is set to %s already",
                 rb_enc_name(fptr->encs.enc));
    }
    if (!io_set_encoding_by_bom(io)) return Qnil;
    return rb_enc_from_encoding(fptr->encs.enc);
}

#statObject

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


1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
# File 'file.c', line 1304

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);
}

#syncBoolean

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

Returns:

  • (Boolean)


2183
2184
2185
2186
2187
2188
2189
2190
2191
# File 'io.c', line 2183

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=(sync) ⇒ Object



2254
2255
2256
2257
2258
2259
# File 'io.c', line 2254

static VALUE
rb_io_set_sync(VALUE io, VALUE sync)
{
    rb_notimplement();
    UNREACHABLE;
}

#sysread(maxlen[, outbuf]) ⇒ String

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"

Returns:



5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
# File 'io.c', line 5136

static VALUE
rb_io_sysread(int argc, VALUE *argv, VALUE io)
{
    VALUE len, str;
    rb_io_t *fptr;
    long n, ilen;
    struct io_internal_read_struct iis;
    int shrinkable;

    rb_scan_args(argc, argv, "11", &len, &str);
    ilen = NUM2LONG(len);

    shrinkable = io_setstrbuf(&str, ilen);
    if (ilen == 0) return str;

    GetOpenFile(io, fptr);
    rb_io_check_byte_readable(fptr);

    if (READ_DATA_BUFFERED(fptr)) {
  rb_raise(rb_eIOError, "sysread for buffered IO");
    }

    /*
     * 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);
    iis.fd = fptr->fd;
    iis.nonblock = 1; /* for historical reasons, maybe (see above) */
    iis.buf = RSTRING_PTR(str);
    iis.capa = ilen;
    n = read_internal_locktmp(str, &iis);

    if (n < 0) {
  rb_sys_fail_path(fptr->pathv);
    }
    io_set_read_length(str, n, shrinkable);
    if (n == 0 && ilen > 0) {
  rb_eof_error();
    }

    return str;
}

#sysseek(offset, whence = IO::SEEK_SET) ⇒ Integer

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

Returns:



5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
# File 'io.c', line 5049

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 < 0 && errno) rb_sys_fail_path(fptr->pathv);

    return OFFT2NUM(pos);
}

#syswrite(string) ⇒ Integer

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

Returns:



5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
5115
# File 'io.c', line 5089

static VALUE
rb_io_syswrite(VALUE io, VALUE str)
{
    VALUE tmp;
    rb_io_t *fptr;
    long n, len;
    const char *ptr;

    if (!RB_TYPE_P(str, T_STRING))
  str = rb_obj_as_string(str);

    io = GetWriteIO(io);
    GetOpenFile(io, fptr);
    rb_io_check_writable(fptr);

    if (fptr->wbuf.len) {
  rb_warn("syswrite for buffered IO");
    }

    tmp = rb_str_tmp_frozen_acquire(str);
    RSTRING_GETMEM(tmp, ptr, len);
    n = rb_write_internal(fptr->fd, ptr, len);
    if (n < 0) rb_sys_fail_path(fptr->pathv);
    rb_str_tmp_frozen_release(str, tmp);

    return LONG2FIX(n);
}

#posInteger #tellInteger

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

Overloads:



1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
# File 'io.c', line 1921

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_ioIO

Returns ios.

Returns:



2406
2407
2408
2409
2410
# File 'io.c', line 2406

static VALUE
rb_io_to_io(VALUE io)
{
    return io;
}

#isattyBoolean #tty?Boolean

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

File.new("testfile").isatty   #=> false
File.new("/dev/tty").isatty   #=> true

Overloads:

  • #isattyBoolean

    Returns:

    • (Boolean)
  • #tty?Boolean

    Returns:

    • (Boolean)


4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
# File 'io.c', line 4371

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

Overloads:

  • #ungetbyte(string) ⇒ nil

    Returns:

    • (nil)
  • #ungetbyte(integer) ⇒ nil

    Returns:

    • (nil)


4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
# File 'io.c', line 4275

VALUE
rb_io_ungetbyte(VALUE io, VALUE b)
{
    rb_io_t *fptr;

    GetOpenFile(io, fptr);
    rb_io_check_byte_readable(fptr);
    switch (TYPE(b)) {
      case T_NIL:
        return Qnil;
      case T_FIXNUM:
      case T_BIGNUM: ;
        VALUE v = rb_int_modulo(b, INT2FIX(256));
        unsigned char c = NUM2INT(v) & 0xFF;
        b = rb_str_new((const char *)&c, 1);
        break;
      default:
        SafeStringValue(b);
    }
    io_ungetbyte(b, fptr);
    return Qnil;
}

#ungetc(string) ⇒ nil

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"

Returns:

  • (nil)


4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
# File 'io.c', line 4314

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

Writes the given strings to ios. The stream must be opened for writing. Arguments that are not a string will be converted to a string using to_s. Returns the number of bytes written in total.

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

Returns:



1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
# File 'io.c', line 1791

static VALUE
io_write_m(int argc, VALUE *argv, VALUE io)
{
    if (argc != 1) {
  return io_writev(argc, argv, io);
    }
    else {
  VALUE str = argv[0];
  return io_write(io, str, 0);
    }
}